<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6007919582257860756</id><updated>2012-02-16T19:14:18.323-08:00</updated><category term='Python'/><category term='Visual Studio'/><category term='xaml'/><category term='textblock'/><category term='c/c++'/><category term='storyboard'/><category term='hashcode'/><category term='New Resources'/><category term='method'/><category term='String.Empty'/><category term='templatedparent'/><category term='grid'/><category term='exceptions'/><category term='conditional'/><category term='menuitem'/><category term='console'/><category term='Main()'/><category term='exception handling'/><category term='content presenter'/><category term='animation'/><category term='WindowState'/><category term='frameworkelementfactory'/><category term='class'/><category term='random numbers'/><category term='layout'/><category term='.net'/><category term='canvas'/><category term='image'/><category term='preprocessor'/><category term='menu'/><category term='if'/><category term='Resource Designer'/><category term='WindowStyle'/><category term='cpu'/><category term='polygon'/><category term='TkInter'/><category term='enum'/><category term='catch'/><category term='select'/><category term='brushes'/><category term='dock'/><category term='dockpanel'/><category term='dragging'/><category term='random'/><category term='property'/><category term='name scope'/><category term='enumeration'/><category term='try/catch'/><category term='throw'/><category term='Java'/><category term='margin'/><category term='button'/><category term='compile'/><category term='opacity'/><category term='paralleltimeline'/><category term='submenu'/><category term='textbox'/><category term='C#'/><category term='LinearGradientBrush'/><category term='introductions'/><category term='brush'/><category term='try'/><category term='namespace'/><category term='wpf'/><category term='icon'/><category term='hash code'/><category term='messagebox'/><category term='ResizeMode'/><category term='binding'/><title type='text'>Understanding C#</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-8888777489519783907</id><published>2010-02-12T23:16:00.000-08:00</published><updated>2010-03-02T19:23:10.216-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><title type='text'>Graphing Calculator Demo -- Part 1</title><content type='html'>&lt;p&gt;It's been nearly a month since my last post but I haven't been idle. I've actually been working hard on a private project and, one day, I may document the steps I took to create it. For now, I'm going to go back to the MSDN samples. This time, I'm not going to bother with a one-to-one port of the program for two reasons: one, it's a very complicated program; two, I want to focus on the logical elements of the program rather than fiddle with the design aspects.&lt;/p&gt;

&lt;p&gt;The topic here is centered on the &lt;a href="http://msdn.microsoft.com/en-us/library/ms771392.aspx"&gt;Graphing Calculator Demo&lt;/a&gt; over at the .NET Framework Library. My goal is to understand the function plotting aspect of the demo. Once I've reached that goal then I may extend this series to include the parametric and 3d graphing but that may take a while since I will continue on with my private project before thinking about that.&lt;/p&gt;

&lt;p&gt;First of all, you will notice that someone commented "This sample have [sic.] bugs when opened in Visual Studio 2008. The xaml design window cannot load the file because of errors." I couldn't comment back or edit that region in either Chrome or IE so I'll just write the solution here to kick things off.&lt;/p&gt;

&lt;p&gt;Go to &lt;em&gt;Window1.xaml&lt;/em&gt; and follow my fix below:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="brush: xml"&gt;
&amp;lt;!--JM: This doesn't work.
          &amp;lt;Setter Property=&amp;quot;Background&amp;quot; Value=&amp;quot;LinearGradient 0,0 0.03,.9 #ffcccccc #ffeeeeee&amp;quot;/&amp;gt;
    Check out below for fix.
--&amp;gt;
&amp;lt;Setter Property=&amp;quot;Background&amp;quot;&amp;gt;
    &amp;lt;Setter.Value&amp;gt;
        &amp;lt;LinearGradientBrush StartPoint=&amp;quot;0,0&amp;quot; EndPoint=&amp;quot;0.03,.9&amp;quot;&amp;gt;
            &amp;lt;GradientStop Color=&amp;quot;#ffcccccc&amp;quot; Offset=&amp;quot;0&amp;quot; /&amp;gt;
            &amp;lt;GradientStop Color=&amp;quot;#ffeeeeee&amp;quot; Offset=&amp;quot;1&amp;quot; /&amp;gt;
        &amp;lt;/LinearGradientBrush&amp;gt;
    &amp;lt;/Setter.Value&amp;gt;
&amp;lt;/Setter&amp;gt;
&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;The most interesting part of this program, for me, is the parser so that's what I will talk about next time.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-8888777489519783907?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/8888777489519783907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2010/02/graphing-calculator-demo-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/8888777489519783907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/8888777489519783907'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2010/02/graphing-calculator-demo-part-1.html' title='Graphing Calculator Demo -- Part 1'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-5679986315215592360</id><published>2010-01-14T21:01:00.000-08:00</published><updated>2010-03-02T19:17:00.032-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='random numbers'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='random'/><category scheme='http://www.blogger.com/atom/ns#' term='layout'/><category scheme='http://www.blogger.com/atom/ns#' term='animation'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='hash code'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='canvas'/><category scheme='http://www.blogger.com/atom/ns#' term='hashcode'/><title type='text'>Concentric Rings Demo -- Part 2</title><content type='html'>&lt;p&gt;Since &lt;a href="http://understanding-c-sharp.blogspot.com/2010/01/concentric-rings-demo-part-1.html"&gt;the window is working&lt;/a&gt; nicely, I want to start drawing onto the canvas.&lt;/p&gt;

&lt;p&gt;The final line of the constructor is &lt;code&gt;CreateCircles();&lt;/code&gt; which initializes some parameters for generating the circles then goes into a loop to instantiate and set-up each of the circles.&lt;/p&gt;

&lt;p&gt;Every circle will be centered at (actually, near) the center of the canvas. It is very simple to find the center of the canvas:&lt;/p&gt;
&lt;pre class="brush: csharp"&gt;
double centerX = this.MainCanvas.ActualWidth / 2.0;
double centerY = this.MainCanvas.ActualHeight / 2.0;
&lt;/pre&gt;

&lt;p&gt;We don't know the size of each person's screen so use the "ActualWidth/ActualHeight" property to get the rendered dimensions of the canvas width and height respectively. It is possible to set the height and width using the "Width/Height" property but it may not be rendered with that value for &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.height.aspx"&gt;a variety of reasons&lt;/a&gt; (here about the height of the object):&lt;/p&gt;

&lt;blockquote&gt;Height is one of three writable properties on FrameworkElement that specify height information. The other two are MinHeight and MaxHeight. If there is a conflict between these values, the order of application for actual height determination is that first MinHeight must be honored, then MaxHeight, and finally, if it is within bounds, Height.&lt;/blockquote&gt;

&lt;p&gt;The next thing in the "CreateCircles" method is the list of valid colors for each circle:&lt;/p&gt;
&lt;pre class="brush: csharp"&gt;
Color[] colors = new Color[] { Colors.White, Colors.Green, Colors.Green, Colors.Lime };
&lt;/pre&gt;

&lt;p&gt;Just a simple array of colors, this is good programming practice when you have a specific style in mind or otherwise already know which values should be valid as you then have a specific object with which you can check against to determine if a value is valid or which can be iterated through to retrieve valid values. In this case, we want to choose a color during the for-loop and with this approach we can just choose an arbitrary element from the colors list. To change the aesthetic, it's simply a matter of reorganizing the list rather than finding and changing all the hard-coded values.&lt;/p&gt;

&lt;p&gt;The colors and center of the canvas are the only values needed to be determined before the loop. Actually, that's not quite true...many of the values are randomized. The random number object is instantiated in the constructor and the variable for it is declared as an instance variable beforehand:&lt;/p&gt;
&lt;pre class="brush: csharp"&gt;
public partial class Window1 : Window
{
    ...
    private Random rand;
    public Window1()
        {
            ...
            rand = new Random(this.GetHashCode());
            ...
        }
    ...
}
&lt;/pre&gt;

&lt;p&gt;As noted in the comments of &lt;a href="http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx"&gt;the GetHashCode documentation&lt;/a&gt;, it's not very useful on its own and, I might add, really not useful as a seed for a random number generator. In this case, the object is never different so the seed will always be the same so the random numbers will always have the same sequence. You can see this by running the program more than once--it's always the same. I would rather seed it with the time the program is run, that way the user will always get something exciting so I used "Environment.TickCount" instead of "this.GetHashCode()" for my rewrite.&lt;/p&gt;

&lt;p&gt;When I was looking at the code, I noticed that while the animation looks like each circle is being created at a different time, the loop is instantiating them all at once. I saw each animation was set with a delay and concluded that that's where the magic happens. To find out if I was right, I commented out all the animation stuff in the for-loop to leave only:&lt;/p&gt;
&lt;pre class="brush: csharp"&gt;
Ellipse e = new Ellipse();
byte alpha = (byte)rand.Next(96,192);
int colorIndex = rand.Next(4);
e.Stroke = new SolidColorBrush(Color.FromArgb(alpha, colors[colorIndex].R, colors[colorIndex].G, colors[colorIndex].B));
e.StrokeThickness = rand.Next(1, 4);
e.Width = 0.0;
e.Height = 0.0;
double offsetX = 16 - rand.Next(32);
double offsetY = 16 - rand.Next(32);

this.MainCanvas.Children.Add(e);                

e.SetValue(Canvas.LeftProperty, centerX + offsetX);
e.SetValue(Canvas.TopProperty, centerY + offsetY);
&lt;/pre&gt;
&lt;p&gt;Note: Elipses are shapes, they need &lt;code&gt;using System.Windows.Shapes;&lt;/code&gt; at the top.&lt;/p&gt;

&lt;p&gt;Of course, without the animation, the circles will not grow so I set "e.Width" and "e.Height" to "10.0" for testing purposes. Curiously, those 24 little circles were in the top-left corner of the screen rather than the center. I traced the problem to not inserting &lt;code&gt;this.Show();&lt;/code&gt; before calling the "CreateCircles" method. What that extra line does is force the window to render along with all its child elements (namely the maximized canvas) that way the layout manager will know where the center is.&lt;/p&gt;

&lt;p&gt;All that's left to do is animate and since I learned about that (in more detail) from both the &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-6.html"&gt;Alarm Clock Sample&lt;/a&gt; and &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-6.html"&gt;Calculator Demo&lt;/a&gt;, I'm not going to cover it here. I will just note that these animation do not rely on a storyboard, a random delay (&lt;code&gt;offsetXAnimation.BeginTime = TimeSpan.FromSeconds(delay);&lt;/code&gt;) is used to make it look like the circles are created at different times, and remember to put &lt;code&gt;using System.Windows.Media.Animation;&lt;/code&gt; at the top.&lt;/p&gt;

&lt;p&gt;Also, this works perfectly well without the "DispatcherTimer" and "lastTick" variables. I fail to understand their use here. Perhaps I will learn later.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-5679986315215592360?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/5679986315215592360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2010/01/concentric-rings-demo-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/5679986315215592360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/5679986315215592360'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2010/01/concentric-rings-demo-part-2.html' title='Concentric Rings Demo -- Part 2'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-565473906082771685</id><published>2010-01-12T21:14:00.000-08:00</published><updated>2010-03-02T19:04:08.871-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WindowState'/><category scheme='http://www.blogger.com/atom/ns#' term='brush'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='brushes'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='property'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='ResizeMode'/><category scheme='http://www.blogger.com/atom/ns#' term='canvas'/><category scheme='http://www.blogger.com/atom/ns#' term='WindowStyle'/><title type='text'>Concentric Rings Demo -- Part 1</title><content type='html'>&lt;p&gt;Finally something with more code and less markup...actually, a lot less markup. The only object in markup besides the main application window is a Canvas for drawing the rings. There will be no need to create a method akin to "InitializeComponent" this time and I will be able to really focus on C# and .NET without worrying about how to translate from XAML.&lt;/p&gt;

&lt;p&gt;Here's the full translation of the XAML for the window:&lt;/p&gt;

&lt;pre class="brush: csharp"&gt;
public class Window1 : Window
{
    Canvas MainCanvas;

    public Window1()
    {
        //&amp;lt;window ...=&amp;quot;&amp;quot; title=&amp;quot;Concentric Rings&amp;quot; width=&amp;quot;910&amp;quot; height=&amp;quot;512&amp;quot;&amp;gt;
        this.Title = &amp;quot;Concentric Rings&amp;quot;;
        this.Width = 910;
        this.Height = 512;

        //&amp;lt;canvas name=&amp;quot;MainCanvas&amp;quot; background=&amp;quot;#FFE0E0E0&amp;quot;&amp;gt;&amp;lt;/canvas&amp;gt;
        MainCanvas = new Canvas();
        BrushConverter bc = new BrushConverter();
        SolidColorBrush brush = bc.ConvertFromString(&amp;quot;#FFE0E0E0&amp;quot;) as SolidColorBrush;
        MainCanvas.Background = brush;

        this.Content = MainCanvas;

    }
}
&lt;/pre&gt;

&lt;p&gt;That's enough to get the window to show up with a gray canvas. The background was a little tricky. The "Background" property must be assigned a "Brush" type so I knew just setting it equal to the string wouldn't work. I noticed the "BrushConverter" class thanks to Visual Studio's autocomplete feature but I wanted to make sure I used it correctly so I searched the internet and found &lt;a href="http://social.msdn.microsoft.com/forums/en-US/wpf/thread/fb164db0-c169-4d0e-85dc-c79163ea3aac/"&gt;the perfect example&lt;/a&gt;. I also made a note to myself that "Canvas" comes from "System.Windows.Controls" and "BrushConverter" (as well as all other brush/color related stuff) comes from "System.Windows.Media".&lt;/p&gt;

&lt;p&gt;All the rest of the code is already written so all I need to do is come to understand it. I want to finish the container before getting the circles to appear.&lt;/p&gt;

&lt;p&gt;It is very useful to be able to control how the window looks to the user. Sometimes you want them to be able to resize, sometimes you want to remove the border. For the concentric rings, we want the window to be maximized, without any border or titlebar and without showing the taskbar.&lt;/p&gt;

&lt;p&gt;These are the three important lines:&lt;/p&gt;
&lt;pre class="brush: csharp"&gt;
this.WindowState = WindowState.Maximized;
this.WindowStyle = WindowStyle.None;
this.ResizeMode = ResizeMode.NoResize;
&lt;/pre&gt;

&lt;p&gt;I tried different combinations. Without any of those lines, the window looks like a normal application. By setting "WindowStyle.None", the titlebar (and buttons) disappear but it still has the border so it can be resized. If you keep the window style normal but set "ResizeMode.NoResize", you regain the title bar and still have a border but cannot change the size of the window. It is only with both "WindowStyle.None" and "ResizeMode.NoResize" does the boarder disappear. That's nice, but we want it to be maximized. Set "WindowState.Maximized" and you get a normal looking maximized window. Set "ResizeMode.NoResize" and magically, the taskbar disappears. What if we say it can be resized but get rid of the title bar? It still forces the taskbar away. So if we want it maximized, why go through the trouble of setting "NoResize" if it's not needed to get the look we want? Well, if you "alt-tab" to another program, you can see the taskbar, then you can right click on "Concentric Rings" and, if you set "NoResize", then you won't be able to restore the window, it will always be maximized. I personally think it would be better to have a windowed and fullscreen mode but perhaps that introduces unnecessary complications...I also think it's strange the programmer wants to force the window to stay maximized but set the "Width" and "Height" properties in XAML.&lt;/p&gt;

&lt;p&gt;Since the window will be maximized at all times with no buttons or other GUI, it would be nice to offer a way to close the application without resorting to the "alt-tab" trick. For the last part of this part, I'll look at quitting with the "Escape" key.&lt;/p&gt;

&lt;p&gt;It's very simple, especially if you've worked with any user interaction before. Just set the event handler for a keypress, check which key, and act appropriately:&lt;/p&gt;

&lt;pre class="brush: csharp"&gt;
public Window1()
{
    ...
    this.KeyDown += new System.Windows.Input.KeyEventHandler(Window1_KeyDown);
    ...
}

void Window1_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
    if (e.Key == System.Windows.Input.Key.Escape)
            this.Close();
}
&lt;/pre&gt;

&lt;p&gt;This is very similar to &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-3.html"&gt;the Calculator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next time, I will try to understand the use of:&lt;/p&gt;
&lt;pre class="brush: csharp"&gt;
System.Windows.Threading.DispatcherTimer frameTimer;
private int lastTick;
private Random rand;
&lt;/pre&gt;

&lt;p&gt;We've done animation without those objects before, so why use them now?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-565473906082771685?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/565473906082771685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2010/01/concentric-rings-demo-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/565473906082771685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/565473906082771685'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2010/01/concentric-rings-demo-part-1.html' title='Concentric Rings Demo -- Part 1'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-4648308063467734170</id><published>2010-01-06T21:18:00.000-08:00</published><updated>2010-03-02T18:56:43.319-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='dockpanel'/><category scheme='http://www.blogger.com/atom/ns#' term='dock'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='submenu'/><category scheme='http://www.blogger.com/atom/ns#' term='grid'/><category scheme='http://www.blogger.com/atom/ns#' term='menu'/><category scheme='http://www.blogger.com/atom/ns#' term='menuitem'/><title type='text'>Calculator Demo -- Part 9</title><content type='html'>&lt;p&gt;Getting the &lt;a href="http://understanding-c-sharp.blogspot.com/2010/01/calculator-demo-part-8.html"&gt;memory function&lt;/a&gt; to work was very similar to setting up the buttons so I didn't need to look up anything new. I had never seen menus for .NET yet so I did need to look up a couple things. Overall, however, it was extremely simple and didn't take much time at all.&lt;/p&gt;

&lt;p&gt;As one would expect, rendering menus is very repetitive. I will only detail the "View" menu since that required a "checkable" menu item which makes it more interesting.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rendering the menu
&lt;ul&gt;
&lt;li&gt;XAML:
&lt;pre class="brush: xml"&gt;
&amp;lt;menu dockpanel.dock=&amp;quot;Top&amp;quot; height=&amp;quot;26&amp;quot;&amp;gt;
    ...
    &amp;lt;menuitem header=&amp;quot;View&amp;quot;&amp;gt;
         &amp;lt;menuitem name=&amp;quot;StandardMenu&amp;quot; click=&amp;quot;OnMenuStandard&amp;quot; ischeckable=&amp;quot;true&amp;quot; ischecked=&amp;quot;True&amp;quot; header=&amp;quot;Standard&amp;quot;&amp;gt;&amp;lt;/menuitem&amp;gt;
    &amp;lt;/menuitem&amp;gt;
    ...
&amp;lt;/menu&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;C#:
&lt;pre class="brush: csharp"&gt;
Menu menu = new Menu();
DockPanel.SetDock(menu, Dock.Top);
menu.Height = 26;
...
MenuItem view = new MenuItem();
view.Header = &amp;quot;View&amp;quot;;
StandardMenu = new MenuItem();
StandardMenu.Name = &amp;quot;StandardMenu&amp;quot;;
StandardMenu.Click += new RoutedEventHandler(OnMenuStandard);
StandardMenu.IsCheckable = true;
StandardMenu.IsChecked = true;
StandardMenu.Header = &amp;quot;Standard&amp;quot;;
view.Items.Add(StandardMenu);
menu.Items.Add(view);
...
MyPanel.Children.Add(menu);
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Notes:
&lt;p&gt;The menu bar is set up first and is defined to be docked to the top of the window's DockPanel. The DockPanel was set up a long time ago to hold the grid. The grid was not docked so I guess DockPanel automatically places other children one after the other if they are not explicitly docked to a certain place. Here, the menu is docked to the top with &lt;code&gt;DockPanel.SetDock(menu, Dock.Top);&lt;/code&gt;. I had a little trouble finding that but the .NET Framework Class Library pointed me in &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.dockpanel.dock.aspx"&gt;the right direction&lt;/a&gt;. My other problem was how to add children to the menus because there are a lot of collections and "add" methods to &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.menuitem.aspx"&gt;the "MenuItem" class&lt;/a&gt;. I was told "The submenu of the MenuItem is made up of the objects within the ItemCollection of a MenuItem." but I had to do some digging to discover "Items.Add(...)" was &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.items.aspx"&gt;the way to go&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;p&gt;&lt;/p&gt;
&lt;li&gt;Making it do something
&lt;ul&gt;
&lt;li&gt;C#:
&lt;pre class="brush: csharp"&gt;
void OnMenuStandard(object sender, RoutedEventArgs e)
{
    //((MenuItem)ScientificMenu).IsChecked = false;
    ((MenuItem)StandardMenu).IsChecked = true; //for now always Standard
}
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Notes:
&lt;p&gt;I didn't have to change this at all. The original programmer was kind to leave a comment for how this is really supposed to work. There really should be two menu items to mirror windows calculator: one for the standard view and another for the scientific view. To keep things simple, there's no scientific view so there's no other menu item. For now, clicking this menu item keeps everything the same but it's clear how to modify it to add a scientific view, and how to manipulate other menu items.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I should mention that I declared "StandardMenu" outside all the methods so that it could be used by both the "InitializeThis" (for set-up) and "OnMenuStandard" (for action) methods.&lt;/p&gt;

&lt;p&gt;Both versions now look and act exactly the same way (they both have the same bugs consequently). The&lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-6.html"&gt; Alarm Clock Sample&lt;/a&gt; port I wrote ended up having a smaller executable than the original but, for this calculator, the port is larger. That's interesting to me. I wonder where the difference lies.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-4648308063467734170?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/4648308063467734170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2010/01/calculator-demo-part-9.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/4648308063467734170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/4648308063467734170'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2010/01/calculator-demo-part-9.html' title='Calculator Demo -- Part 9'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-8632803395549623316</id><published>2010-01-05T21:52:00.000-08:00</published><updated>2010-03-02T18:48:54.297-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='class'/><category scheme='http://www.blogger.com/atom/ns#' term='conditional'/><category scheme='http://www.blogger.com/atom/ns#' term='layout'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='textblock'/><category scheme='http://www.blogger.com/atom/ns#' term='method'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='grid'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='property'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='if'/><category scheme='http://www.blogger.com/atom/ns#' term='textbox'/><title type='text'>Calculator Demo -- Part 8</title><content type='html'>&lt;p&gt;The last thing I wanted to do was complete the calculator's memory. I saved it for last because I thought it would be very simple after finishing everything else. [Unfortunatley, &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-7.html"&gt;I lied&lt;/a&gt;. The memory won't be the last thing to do. I forgot about the menu, but that should be even easier.] I noticed that the original code used a class called "PaperTrail" which is the last class defined in &lt;em&gt;window1.xaml.cs&lt;/em&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PaperTrail
&lt;ul&gt;
&lt;li&gt;C#:
&lt;pre class="brush: csharp"&gt;
private class PaperTrail
{
    string args;
    
    public PaperTrail()
    {
    }
    public void AddArguments(string a)
    {
        args = a;
    }
    public void AddResult(string r)
    {
        PaperBox.Text += args + &amp;quot; = &amp;quot; + r + &amp;quot;\n&amp;quot;;
    }
    public void Clear()
    {
        PaperBox.Text = string.Empty;
        args = string.Empty;
    }
}
        &lt;/pre&gt;&lt;/li&gt;
        &lt;li&gt;Notes:
        &lt;p&gt;This is a very simple class. The constructor takes no arguments and does nothing. The only three methods are very simple in terms of how complex the code is but they don't do what I expected them to do. I thought something described as a "paper trail" would keep a record of the trail but it does no such thing. It calls upon "PaperBox" to keep the record. &lt;/p&gt;
        &lt;/li&gt;
        &lt;/ul&gt;
        &lt;/li&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;li&gt;PaperBox
        &lt;ul&gt;
        &lt;li&gt;C#:
        &lt;pre class="brush: csharp"&gt;
        static MyTextBox PaperBox;
        ...
        PaperBox = new MyTextBox();
        Grid.SetRow(PaperBox, 1);
        Grid.SetColumn(PaperBox, 0);
        Grid.SetColumnSpan(PaperBox, 3);
        Grid.SetRowSpan(PaperBox, 5);
        PaperBox.IsReadOnly = true;
        PaperBox.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
        PaperBox.Margin = new Thickness(3.0,1.0,1.0,1.0);
        PaperBox.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
        &lt;/pre&gt;&lt;/li&gt;
        &lt;li&gt;Notes:
        &lt;p&gt;You can find "PaperBox" defined at the top of the "Window1" class definition. It is simply a textbox like "&lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-4.html"&gt;DisplayBox&lt;/a&gt;" but subclassed differently in the "Window1" constructor to have a different size using the "SetColumnSpan" and "SetRowSpan" methods, different interaction by setting the "IsReadOnly" property to "true", and a different visual style by making the scroll bars visible, and setting up the margins.&lt;/p&gt;
        &lt;/li&gt;
        &lt;/ul&gt;
        &lt;/li&gt;
        &lt;/ul&gt;
        
        &lt;p&gt;Now that there's a place to store memory information, there need to be appropriate buttons to interact with the memory. Microsoft's programmer decided to have Memory Clear, Memory Save, Memory Recall, and Memory Plus operations. The are found in the "ProcessOperation" method &lt;em&gt;//Comments by original programmer&lt;/em&gt;:&lt;/p&gt;
        
        &lt;ul&gt;
        &lt;li&gt;Memory Clear
        &lt;ul&gt;
        &lt;li&gt;C#:
        &lt;pre class="brush: csharp"&gt;
        case &amp;quot;BMemClear&amp;quot;:
            Memory = 0.0F;
            DisplayMemory();
            break;
        &lt;/pre&gt;&lt;/li&gt;
        &lt;li&gt;Notes:
        &lt;p&gt;The memory value is stored as a string "_mem_val" accessed through the property "Memory". Here we want to clear the memory, so the mathematical thing to do is set it to 0 (floating point of course). All of the operations which alter memory call the "DisplayMemory" method.&lt;/p&gt;
        &lt;/li&gt;
        &lt;/ul&gt;
        &lt;/li&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;li&gt;Memory Save
        &lt;ul&gt;
        &lt;li&gt;C#:
        &lt;pre class="brush: csharp"&gt;
        case &amp;quot;BMemSave&amp;quot;:
            Memory = Convert.ToDouble(Display);
            DisplayMemory();
            EraseDisplay = true;
            break;
        &lt;/pre&gt;&lt;/li&gt;
        &lt;li&gt;Notes:
        &lt;p&gt;Because of &lt;code&gt;EraseDisplay = true;&lt;/code&gt;, if you save the display to memory when you are in the middle of an operation, you need to key-in another value (maybe the same one) if you want to perform a binary operation. That is, the number is saved to memory and continues to be displayed but any binary operation will not see it. Unary operations just take the value from the display so they will work as expected.&lt;/p&gt;
        &lt;/li&gt;
        &lt;/ul&gt;
        &lt;/li&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;li&gt;Memory Recall
        &lt;ul&gt;
        &lt;li&gt;C#:
        &lt;pre class="brush: csharp"&gt;
        case &amp;quot;BMemRecall&amp;quot;:
            Display = /*val =*/ Memory.ToString();
            UpdateDisplay();
            //if (LastOper != Operation.None)   //using MR is like entring a digit
                EraseDisplay = false;
            break;
        &lt;/pre&gt;&lt;/li&gt;
        &lt;li&gt;Notes:
        &lt;p&gt;Because of "EraseDisplay = false;", memory recall is like entering a digit. I guess the commented-out partial conditional would have been to make MR act like completing a binary operation with the saved value.&lt;/p&gt;
        &lt;/li&gt;
        &lt;/ul&gt;
        &lt;/li&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;li&gt;Memory Plus
        &lt;ul&gt;
        &lt;li&gt;C#:
        &lt;pre class="brush: csharp"&gt;
        case &amp;quot;BMemPlus&amp;quot;:
            d = Memory + Convert.ToDouble(Display);
            Memory = d;
            DisplayMemory();
            EraseDisplay = true;
            break;
        &lt;/pre&gt;&lt;/li&gt;
        &lt;li&gt;Notes:
        &lt;p&gt;The value in the display is added to the value in memory and then saved in memory. Like "BMemSave", this effectively erases the display so binary operations won't see it.&lt;/p&gt;
        &lt;/li&gt;
        &lt;/ul&gt;
        &lt;/li&gt;
        &lt;/ul&gt;
        
        &lt;p&gt;The DisplayMemory method is a bit naughty. It accesses "_mem_val" directly instead of through the "Memory" property. The author went through pains to start the variable name with an underscore so you would expect him to follow the practice of pretending he can't access it without the approperiate getter.... Anyway, it also uses a certain object called "BMemBox" which is defined in XAML so I had to port it to C#:&lt;/p&gt;
        &lt;ul&gt;
        &lt;li&gt;Memory Display Box
        &lt;ul&gt;
        &lt;li&gt;XAML:
        &lt;pre class="brush: xml"&gt;
        &amp;lt;textblock name=&amp;quot;BMemBox&amp;quot; grid.column=&amp;quot;3&amp;quot; grid.row=&amp;quot;1&amp;quot; margin=&amp;quot;10,17,10,17&amp;quot; grid.columnspan=&amp;quot;2&amp;quot;&amp;gt;Memory: [empty]&amp;lt;/textblock&amp;gt;
        &lt;/pre&gt;&lt;/li&gt;
        &lt;li&gt;C#:
        &lt;pre class="brush: csharp"&gt;
        BMemBox = new TextBlock();
        BMemBox.Name = &amp;quot;BMemBox&amp;quot;;
        Grid.SetColumn(BMemBox, 3);
        Grid.SetRow(BMemBox, 1);
        BMemBox.Margin = new Thickness(10.0, 17.0, 10.0, 17.0);
        Grid.SetColumnSpan(BMemBox, 2);
        BMemBox.Text = &amp;quot;Memory: [empty]&amp;quot;;
        MyGrid.Children.Add(BMemBox);
        &lt;/pre&gt;&lt;/li&gt;
        &lt;li&gt;Notes:
        &lt;p&gt;This is very similar to &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-6.html"&gt;rendering the buttons&lt;/a&gt; but there's no click event. The styles are all default too.&lt;/p&gt;
        &lt;/li&gt;
        &lt;/ul&gt;
        &lt;/li&gt;
        &lt;/ul&gt;
        
        &lt;p&gt;I thought this would be the last part to the Calculator Demo series but I forgot about the menu. The next part should be the last part then I will get to choose another program to analyse.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-8632803395549623316?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/8632803395549623316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2010/01/calculator-demo-part-8.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/8632803395549623316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/8632803395549623316'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2010/01/calculator-demo-part-8.html' title='Calculator Demo -- Part 8'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-6149579147068976229</id><published>2009-12-31T05:22:00.000-08:00</published><updated>2010-03-01T01:51:41.045-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='throw'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='exception handling'/><category scheme='http://www.blogger.com/atom/ns#' term='conditional'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='method'/><category scheme='http://www.blogger.com/atom/ns#' term='String.Empty'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='if'/><category scheme='http://www.blogger.com/atom/ns#' term='exceptions'/><category scheme='http://www.blogger.com/atom/ns#' term='console'/><title type='text'>Calculator Demo -- Part 7</title><content type='html'>&lt;p&gt;I discovered &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-6.html"&gt;last time&lt;/a&gt; that every operation button invokes the "OperBtn_Click" event handler on click which calls the "ProcessOperation" method with the appropriate argument. I want to briefly touch upon each operation in the switch statement of both the "ProcessOperation" and "Calc" methods.&lt;/p&gt;

&lt;p&gt;ProcessOperation &lt;em&gt;//Comments by original programmer&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Division
&lt;ul&gt;
&lt;li&gt;C#:
&lt;pre class="brush: csharp"&gt;
                case &amp;quot;BDevide&amp;quot;:
                    if (EraseDisplay)    //stil wait for a digit...
                    {  //stil wait for a digit...
                        LastOper = Operation.Devide;
                        break;
                    }
                    CalcResults();
                    LastOper = Operation.Devide;
                    LastValue = Display;
                    EraseDisplay = true;
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;Many of these are binary operations so if the display has not changed since the last operation that means a second number has not been entered. All of these binary operations wait for a second digit before trying to perform their respective operation or the results wouldn't make sense. Also of note is that these binary operations overwrite "LastOper" with themselves so that they will be performed when the next operation is clicked (this means the order of operations for this calculator is strictly left to right).&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Multiplication
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case &amp;quot;BMultiply&amp;quot;:
                    if (EraseDisplay)    //stil wait for a digit...
                    {  //stil wait for a digit...
                        LastOper = Operation.Multiply;
                        break;
                    }
                    CalcResults();
                    LastOper = Operation.Multiply;
                    LastValue = Display;
                    EraseDisplay = true;
                    break;
                
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;Another binary operation like above so it follows the same scheme. If a division occurred before this case, "EraseDisplay" would be true so it would wait for the next digit. If a numerical key was pressed, "EraseDisplay" would be false so the last operation would be calculated (for example, division) and then "LastOper" would be set up so that the multiplication happens next (as long as a numerical key is pressed next).&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Subtraction
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case &amp;quot;BMinus&amp;quot;:
                    if (EraseDisplay)    //stil wait for a digit...
                    {  //stil wait for a digit...
                        LastOper = Operation.Subtract;
                        break;
                    }
                    CalcResults();
                    LastOper = Operation.Subtract;
                    LastValue = Display;
                    EraseDisplay = true;
                    break;
                
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;If a numerical key is not pressed after the multiplication button--say, the subtraction button is pressed instead--then "LastOper" will be overridden by the subtraction. In this case, a multiplication would not be performed next, a subtraction would be in the wings. &lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Addition
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case &amp;quot;BPlus&amp;quot;:
                    if (EraseDisplay)
                    {  //stil wait for a digit...
                        LastOper = Operation.Add;
                        break;
                    }
                    CalcResults();
                    LastOper = Operation.Add;
                    LastValue = Display;
                    EraseDisplay = true;
                    break;
                
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;It's clear that the "ProcessOperation" method does not perform the actual operation. This method only sets up the operation for the calculation and asks for the calculation to be performed under the right conditions. One would think, it must be the "CalcResults" method which must be performing the operation. That's almost correct. As I investigated &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-6.html"&gt;previously&lt;/a&gt;, "CalcResults" does one more check &lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Solution
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case &amp;quot;BEqual&amp;quot;:
                    if (EraseDisplay)    //stil wait for a digit...
                        break;
                    CalcResults();
                    EraseDisplay = true;
                    LastOper = Operation.None;
                    LastValue = Display;
                    //val = Display;
                    break;
                
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;This isn't a binary operation so why is it waiting for a second digit? I think they just don't want "=" to override any previous operation until there's actually something to calculate. That last comment is a little puzzling to me as well. I guess there was a variable "val" used to store the result but it's not needed since the display is already holding the result so you can always query the display to get the previous result.&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Take the square root
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case &amp;quot;BSqrt&amp;quot;:
                    LastOper = Operation.Sqrt;
                    LastValue = Display;
                    CalcResults();
                    LastValue = Display;
                    EraseDisplay = true;
                    LastOper = Operation.None;
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;Finally, we get an example of a unary operation. It doesn't need to check if the display is empty, it just operates on whatever is in the display. The display defaults to "0" so there's no problem pushing the square root button immediately after starting the program. All the unary operations set "LastOper" and "LastValue" at the start. They set them again after the calculation if needed just like the binary operations.&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Multiply by a percent
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case &amp;quot;BPercent&amp;quot;:
                    if (EraseDisplay)    //stil wait for a digit...
                    {  //stil wait for a digit...
                        LastOper = Operation.Percent;
                        break;
                    }
                    CalcResults();
                    LastOper = Operation.Percent;
                    LastValue = Display;
                    EraseDisplay = true;
                    //LastOper = Operation.None;
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;I wish percent acted as a unary operation, just dividing your number by 100 and displaying the result. But here, it is used as a binary operation for multiplying one number by another number's percentage value. You can't see that from the above except for the hint that given by the conditional that it is a binary operation. I will talk about the "Calc" method later to revisit how each operation is actually performed in code.&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Take the reciprocal 
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case &amp;quot;BOneOver&amp;quot;:
                    LastOper = Operation.OneX;
                    LastValue = Display;
                    CalcResults();
                    LastValue = Display;
                    EraseDisplay = true;
                    LastOper = Operation.None;
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;This is the final mathematical unary operation. It doesn't look much different from &lt;code&gt;case "BSqrt"&lt;/code&gt; except for the names.&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Clear all
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case &amp;quot;BC&amp;quot;:
                    LastOper = Operation.None;
                    Display = LastValue = string.Empty;
                    //Paper.Clear();
                    UpdateDisplay();
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;This is one of the operations which doesn't perform any calculations. It only operates on some variables to, well, clear them. "LastOper" is cleared with "Operation.None", "Display" and "LastValue" are cleared with "string.Empty", and "Paper", which is the history I haven't yet looked into, is cleared with its "Clear" method.&lt;/p&gt;
                
                A couple interesting things about C# is that there is a constant "string.Empty" supplied out of the box (which actually works differently than the empty string--""--as mentioned in &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-4.html"&gt;Part 4&lt;/a&gt;) and that assignment is carried out right-to-left so &lt;code&gt;Display = LastValue = string.Empty;&lt;/code&gt; makes sense and works as expected.
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Clear Entry
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case &amp;quot;BCE&amp;quot;:
                    LastOper = Operation.None;
                    Display = LastValue;
                    UpdateDisplay();
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;If you notice you've made a mistake before you push "=", you can undo it by pressing "CE". This cancels whatever operation you've asked the calculator to perform and then sets the display to the last value showing before you keyed in another. Of course, this will only work with binary operations as the unary operations automatically carry out the calculation. &lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;/ul&gt;
                
                Calc &lt;em&gt;[I will ignore any line that references "Paper"]&lt;/em&gt;
                &lt;ul&gt;
                &lt;li&gt;Division
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case Operation.Devide:
                    Paper.AddArguments(LastValue + &amp;quot; / &amp;quot; + Display);
                    d = (Convert.ToDouble(LastValue) / Convert.ToDouble(Display));
                    CheckResult(d);
                    Paper.AddResult(d.ToString());
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;In order to do math, all values must be numerical types. Recall that "LastValue" and "Display" are strings so they have to be converted to a numerical type. In this case, they are converted to doubles which are 64bit floating point numbers. C# doesn't complain about infinities when dealing with floating point numbers and that makes sense given the &lt;a href="http://en.wikipedia.org/wiki/Floating_point#Special_values"&gt;IEEE specificiation&lt;/a&gt;. The "CheckResult" method is used to discover values that don't make sense (for this calculator).&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Addition
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case Operation.Add:
                    Paper.AddArguments(LastValue + &amp;quot; + &amp;quot; + Display);
                    d = Convert.ToDouble(LastValue) + Convert.ToDouble(Display);
                    CheckResult(d);
                    Paper.AddResult(d.ToString());
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;Recall that "LastValue" is the value shown in the display before the second operand is entered and "Display" is what is shown to the user. At this point, "Display" still holds the value of the second operand. The display will be updated after the final answer, stored in "d" is returned to the "CalcResults" method.&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Multiplication
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case Operation.Multiply:
                    Paper.AddArguments(LastValue + &amp;quot; * &amp;quot; + Display);
                    d = Convert.ToDouble(LastValue) * Convert.ToDouble(Display);
                    CheckResult(d);
                    Paper.AddResult(d.ToString());
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;For all of these operations, you just need to look at the assignment to "d" for how the operation is performed. Here, we want to multiply so "LastValue" and "Display" are converted from strings to doubles and then multiplied with the result stored in "d".&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Multiply by a percent
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case Operation.Percent:
                    //Note: this is different (but make more sense) then Windows calculator
                    Paper.AddArguments(LastValue + &amp;quot; % &amp;quot; + Display);
                    d = (Convert.ToDouble(LastValue) * Convert.ToDouble(Display)) / 100.0F;
                    CheckResult(d);
                    Paper.AddResult(d.ToString());
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;I don't think this makes more sense than Windows calculator. I would prefer the percent operation to be unary and simply divide the current display by 100 to get ready for whatever operation you want to perform next. When I read 50%, I think of &lt;em&gt;50/100 = 0.5&lt;/em&gt; and end it. I don't think of &lt;em&gt;50 * 1 / 100&lt;/em&gt;. And I definitely don't think of a binary operation.&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Subtraction
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case Operation.Subtract:
                    Paper.AddArguments(LastValue + &amp;quot; - &amp;quot; + Display);
                    d = Convert.ToDouble(LastValue) - Convert.ToDouble(Display);
                    CheckResult(d);
                    Paper.AddResult(d.ToString());
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;The .NET Framework defines a lot of conversion methods within a variety of classes. I haven't looked at them all yet. And that doesn't even include all the different object castings you can perform.&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Take the square root
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case Operation.Sqrt:
                    Paper.AddArguments(&amp;quot;Sqrt( &amp;quot; + LastValue + &amp;quot; )&amp;quot;);
                    d = Math.Sqrt(Convert.ToDouble(LastValue));
                    CheckResult(d);
                    Paper.AddResult(d.ToString());
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;C# doesn't include a native Sqrt operation so it is implemented in the Math namespace.&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                &lt;li&gt;Take the reciprocal
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                case Operation.OneX:
                    Paper.AddArguments(&amp;quot;1 / &amp;quot; + LastValue);
                    d = 1.0F / Convert.ToDouble(LastValue);
                    CheckResult(d);
                    Paper.AddResult(d.ToString());
                    break;
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;This programmer is very OCD about making sure all the numbers are represented as floating points. You don't need to but it's good practice to choose one way and stick to it. Here's a little something I made to test how division in particular is handled:&lt;/p&gt;
                
                
                &lt;blockquote&gt;
                &lt;pre class="brush: csharp"&gt;
                using System;
                
                namespace testconsole
                {
                    class Program
                    {
                        static void Main(string[] args)
                        {
                            Console.WriteLine(7 / 2);
                            Console.WriteLine(7 / 2.0);
                            Console.WriteLine(7 / 2F);
                            Console.WriteLine(7 / 2.0F);
                            
                            Console.WriteLine(7.0 / 2);
                            Console.WriteLine(7.0 / 2.0);
                            Console.WriteLine(7.0 / 2F);
                            Console.WriteLine(7.0 / 2.0F);
                            
                            Console.WriteLine(7F / 2);
                            Console.WriteLine(7F / 2.0);
                            Console.WriteLine(7F / 2F);
                            Console.WriteLine(7F / 2.0F);
                            
                            Console.WriteLine(7.0F / 2);
                            Console.WriteLine(7.0F / 2.0);
                            Console.WriteLine(7.0F / 2F);
                            Console.WriteLine(7.0F / 2.0F);
                            
                            Console.ReadLine();
                        }
                    }
                }
                &lt;/pre&gt;
                
                Result:&lt;br/&gt;
                3&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                3.5&lt;br/&gt;
                &lt;/blockquote&gt;
                &lt;p&gt;Of course, there are other ways to convert integers to floats but those are the most common shorthands.&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;p /&gt;
                
                &lt;/ul&gt;
                
                &lt;p&gt;CheckResults:&lt;/p&gt;
                &lt;ul&gt;
                &lt;li&gt;Discover invalid numbers
                &lt;ul&gt;
                &lt;li&gt;C#:
                &lt;pre class="brush: csharp"&gt;
                private void CheckResult(double d)
                {
                    if (Double.IsNegativeInfinity(d) || Double.IsPositiveInfinity(d) || Double.IsNaN(d))
                        throw new Exception(&amp;quot;Illegal value&amp;quot;);
                }
                &lt;/pre&gt;&lt;/li&gt;
                &lt;li&gt;Notes:
                &lt;p&gt;There is very useful stuff to remember here. The facts that Double has a method to check for +/- infinity as well as values which are not numbers (NaN) and throwing exceptions. Very handy.&lt;/p&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                &lt;/li&gt;
                &lt;/ul&gt;
                
                &lt;p&gt;All that's left is displaying the memory and history (paper trail).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-6149579147068976229?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/6149579147068976229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-7.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/6149579147068976229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/6149579147068976229'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-7.html' title='Calculator Demo -- Part 7'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-5196775716798705285</id><published>2009-12-23T17:44:00.000-08:00</published><updated>2010-02-28T01:55:00.368-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='catch'/><category scheme='http://www.blogger.com/atom/ns#' term='enum'/><category scheme='http://www.blogger.com/atom/ns#' term='exception handling'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='method'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='button'/><category scheme='http://www.blogger.com/atom/ns#' term='exceptions'/><category scheme='http://www.blogger.com/atom/ns#' term='enumeration'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='messagebox'/><category scheme='http://www.blogger.com/atom/ns#' term='animation'/><category scheme='http://www.blogger.com/atom/ns#' term='property'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='try/catch'/><category scheme='http://www.blogger.com/atom/ns#' term='try'/><title type='text'>Calculator Demo -- Part 6</title><content type='html'>&lt;p&gt;For the sake of organization and time, I have completed the animations &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/it-took-so-much-effort-to-style-buttons.html"&gt;as promised&lt;/a&gt; and I added all the other buttons to the grid. However, I only fully implemented the "+/-" operation because I thought it best to visit each operation in the next part.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rendering the buttons
&lt;ul&gt;
&lt;li&gt;XAML:
&lt;pre class="brush: xml"&gt;
&amp;lt;Button Name=&amp;quot;BPM&amp;quot; Click=&amp;quot;OperBtn_Click&amp;quot; Background=&amp;quot;Darkgray&amp;quot; Style=&amp;quot;{StaticResource DigitBtn}&amp;quot;  Grid.Column=&amp;quot;6&amp;quot; Grid.Row=&amp;quot;5&amp;quot; &amp;gt;+/-&amp;lt;/Button&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;C#:
&lt;pre class="brush: csharp"&gt;
Button BPM = new Button();
BPM.Name = &amp;quot;BPM&amp;quot;;
BPM.Click += new RoutedEventHandler(OperBtn_Click);
BPM.Background = Brushes.DarkGray;
BPM.Style = DigitBtn; //try without resources
Grid.SetColumn(BPM, 6);
Grid.SetRow(BPM, 5);
BPM.Content = &amp;quot;+/-&amp;quot;;
MyGrid.Children.Add(BPM);
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Notes:
&lt;p&gt;This is exactly as &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/it-took-so-much-effort-to-style-buttons.html"&gt;the buttons I looked at previously&lt;/a&gt; except with a different event handler: &lt;code&gt;BPM.Click += new RoutedEventHandler(OperBtn_Click);&lt;/code&gt;. Also, when doing some of the other operations there is a tooltip property set (eg. &lt;code&gt;BMemPlus.ToolTip = "Add To Memory";&lt;/code&gt; for the "M+" button).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted the "+/-" button to work as expected so I followed the Click event:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OperBtn_Click
&lt;ul&gt;
&lt;li&gt;C#:
    &lt;pre class="brush: csharp"&gt;
    private void OperBtn_Click(object sender, RoutedEventArgs e)
    {
        ProcessOperation(((Button)sender).Name.ToString());
    }
    &lt;/pre&gt;&lt;/li&gt;
    &lt;li&gt;Notes:
&lt;p&gt;    All the buttons have their name properties set. In the case of the "+/-" button we have &lt;code&gt;BPM.Name = "BPM";&lt;/code&gt;. When the above handler is invoked it will then pass the name of the button as an argument to the ProcessOperation method.&lt;/p&gt;
    &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;p /&gt;
    &lt;li&gt;ProcessOperation
    &lt;ul&gt;
    &lt;li&gt;C#:
    &lt;pre class="brush: csharp"&gt;
    private void ProcessOperation(string s)
    {
        Double d = 0.0;
        switch (s)
        {
            case &amp;quot;BPM&amp;quot;:
            LastOper = Operation.Negate;
            LastValue = Display;
            CalcResults();
            LastValue = Display;
            EraseDisplay = true;
            LastOper = Operation.None;
            break;
            ...
        }
    }
    &lt;/pre&gt;&lt;/li&gt;
    &lt;li&gt;Notes:
&lt;p&gt;    Here we see what happens when calling &lt;code&gt;ProcessOperation("BPM");&lt;/code&gt;. The variable "d" is not applicable to this case. First, the most recently clicked operation is saved into "LastOper" and the most recent value displayed is saved into "LastValue". By doing this before the calculation, the program is overriding whatever operation was clicked beforehand (that means, if you try to do "2*-2" by clicking "2,*,2,+/-" the multiplication will be forgotten). "LastValue" and "LastOper" deserve a closer look later. Next, the calculation is performed by calling "CalcResults". When the calculation is completed, the current display is again saved however the operation is set to null which is force other operations to not negate again. It is very important to do it this way because this calculator works with infix notation. When I first saw &lt;code&gt;EraseDisplay = true;&lt;/code&gt; I thought it meant to actually erase the display but that doesn't make sense. What it is actually doing is taking a note so that the next operation will know whether it should erase the display (in the case of "ProcessKey") or whether to simply treat the display as empty (as in several cases of "ProcessOperation").&lt;/p&gt;
    &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;p /&gt;
    &lt;li&gt;Operation LastOper
    &lt;ul&gt;
    &lt;li&gt;C#:
    &lt;pre class="brush: csharp"&gt;
    private enum Operation
    {
        None,
        Devide,
        Multiply,
        Subtract,
        Add,
        Percent,
        Sqrt,
        OneX,
        Negate
    }
    private Operation LastOper;
    &lt;/pre&gt;&lt;/li&gt;
    &lt;li&gt;Notes:
&lt;p&gt;    I've used enums before for setting many properties in but the &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-5.html"&gt;Alarm Clock Sample&lt;/a&gt; and this &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-3.html"&gt;Calculator Demo&lt;/a&gt; but this is the first time I've really seen how they are useful. Here, they set us up so it will be very clear which operation is being used and we don't need to deal with strings. The compiler gives them numbers which is good for computers and we get a descriptive name which is good for us.&lt;/p&gt;
    &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;p /&gt;
    &lt;li&gt;LastValue
    &lt;ul&gt;
    &lt;li&gt;C#:
    &lt;pre class="brush: csharp"&gt;
    private string LastValue
    {
        get
        {
            if (_last_val == string.Empty)
            return &amp;quot;0&amp;quot;;
            return _last_val;
        }
        set
        {
            _last_val = value;
        }
    }
    &lt;/pre&gt;&lt;/li&gt;
    &lt;li&gt;Notes:
&lt;p&gt;    This is a very simple property declaration but it shows us exactly why getters and setters are useful. This is a calculator application and it's not very mathematical to show an empty display area so it checks if the last value is an empty string (from "Clear All") and returns the string "0".&lt;/p&gt;
    &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;p /&gt;
    &lt;li&gt;CalcResults
    &lt;ul&gt;
    &lt;li&gt;C#:
    &lt;pre class="brush: csharp"&gt;
    private void CalcResults()
    {
        double d;
        if (LastOper == Operation.None)
            return;
        
        d = Calc(LastOper);
        Display = d.ToString();
        
        UpdateDisplay();
    }
    &lt;/pre&gt;&lt;/li&gt;
    &lt;li&gt;Notes:
&lt;p&gt;    First, a variable, "d", is declared to save the numerical result of the upcoming calculation. If there is no operation to be performed (as is the case after "+/-" is completed), this method just returns and nothing happens. However, if there is an operation to be performed it calls the "Calc" method to do the dirty work. The result of the operation is sent to the display and the display is updated. Again, I am very aware of object oriented programming at work (I guess it's actually more of an example of procedural programming since all these functions/methods are in the same class). &lt;/p&gt;
    &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;p /&gt;
    &lt;li&gt;Calc
    &lt;ul&gt;
    &lt;li&gt;C#:
    &lt;pre class="brush: csharp"&gt;
    private double Calc(Operation LastOper)
    {
        double d = 0.0;
        
        try {
            switch (LastOper)
            {
                ...
                case Operation.Negate:
                d = Convert.ToDouble(LastValue) * (-1.0F);
                break;
            }
        }
        catch {
            d = 0;
            Window parent = (Window)MyPanel.Parent;
            //Paper.AddResult(&amp;quot;Error&amp;quot;);
            MessageBox.Show(parent, &amp;quot;Operation cannot be perfomed&amp;quot;, parent.Title);
        }
        
        return d;
    }
    &lt;/pre&gt;&lt;/li&gt;
    &lt;li&gt;Notes:
&lt;p&gt;    Again, I am only highlighting "+/-". The variable "d" is used store the result of the calculation and then we come to a Try/Catch block for exception handling. Many of the operations check the calculation to make sure there's nothing strange like infinities and then throw an exception which will be caught by the "catch" block. I will look at those next time. Notice the Operation.Negate case won't forcefully throw an exception since it's only multiplying the last value displayed by negative one and the last value should have already been checked for sanity. However, if something were to go wrong we can see that the error will be noted by adding it to "Paper" (not relevant now) and a standard message box will be rendered.&lt;/p&gt;
    &lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;/ul&gt;
    
&lt;p&gt;    When you click on a button, a lot of things happen. I think it's really good that I chose to continue the Calculator Demo. In this part, I got to understand enums, try/except, and a bit more about properties and modular code. I will go through the other operations in the next part though I won't have to be nearly as detailed as here.&lt;/p&gt;
    
    
&lt;p&gt;    [update Jan 15, 2010]&lt;/p&gt;
&lt;p&gt;    I just noticed, I never actually talked about the animation though I did actually complete them at the time.&lt;/p&gt;
    
&lt;p&gt;    I will simply post my code with comments (these go in "InitializeThis"):&lt;/p&gt;
    &lt;pre class="brush: csharp"&gt;
    ...
    //&amp;lt;Storyboard x:Key=&amp;quot;playStoryboard&amp;quot;&amp;gt;
    Storyboard playStoryboard = new Storyboard();
    this.RegisterName(&amp;quot;playStoryboard&amp;quot;, playStoryboard);
    //  &amp;lt;DoubleAnimation From=&amp;quot;50&amp;quot;  To=&amp;quot;40&amp;quot; Duration=&amp;quot;0:0:0.25&amp;quot; RepeatBehavior=&amp;quot;1x&amp;quot; AutoReverse=&amp;quot;True&amp;quot; 
    //      Storyboard.TargetName=&amp;quot;TB&amp;quot; Storyboard.TargetProperty=&amp;quot;(Ellipse.Height)&amp;quot;/&amp;gt;
    DoubleAnimation TBHeightAnimation = new DoubleAnimation(50.0, 40.0, new Duration(new TimeSpan(0, 0, 0, 0, 250))); //guess
    TBHeightAnimation.RepeatBehavior = new RepeatBehavior(1.0); //1x gives the error &amp;quot;cannot implicitly convert int to RepeatBehaviour&amp;quot;
    TBHeightAnimation.AutoReverse = true;
    Storyboard.SetTargetName(TBHeightAnimation, &amp;quot;TB&amp;quot;);
    Storyboard.SetTargetProperty(TBHeightAnimation, new PropertyPath(Ellipse.HeightProperty));
    playStoryboard.Children.Add(TBHeightAnimation);
    
    //  &amp;lt;DoubleAnimation From=&amp;quot;50&amp;quot;  To=&amp;quot;44&amp;quot; Duration=&amp;quot;0:0:0.25&amp;quot; RepeatBehavior=&amp;quot;1x&amp;quot; AutoReverse=&amp;quot;True&amp;quot; 
    //      Storyboard.TargetName=&amp;quot;TB&amp;quot; Storyboard.TargetProperty=&amp;quot;(Ellipse.Width)&amp;quot;/&amp;gt;
    DoubleAnimation TBWidthAnimation = new DoubleAnimation(50.0, 44.0, new Duration(new TimeSpan(0, 0, 0, 0, 250)));
    TBWidthAnimation.RepeatBehavior = new RepeatBehavior(1.0);
    TBWidthAnimation.AutoReverse = true;
    Storyboard.SetTargetName(TBWidthAnimation, &amp;quot;TB&amp;quot;);
    Storyboard.SetTargetProperty(TBWidthAnimation, new PropertyPath(Ellipse.WidthProperty));
    playStoryboard.Children.Add(TBWidthAnimation);
    //&amp;lt;/Storyboard&amp;gt;
    MyGrid.Resources.Add(&amp;quot;playStoryboard&amp;quot;, playStoryboard);
    /* The animations make the ellipses become circles... (including Microsoft's) */
    ...
    &lt;/pre&gt;
    
&lt;p&gt;    Near the definition of setter4&lt;/p&gt;
    &lt;pre class="brush: csharp"&gt;
    this.RegisterName(&amp;quot;TB&amp;quot;, TB);
    ...
    //&amp;lt;ControlTemplate.Triggers&amp;gt;
    //    &amp;lt;Trigger Property=&amp;quot;IsMouseOver&amp;quot; Value=&amp;quot;true&amp;quot;&amp;gt;
    Trigger IMO = new Trigger();
    IMO.Property = Button.IsMouseOverProperty; //guess
    IMO.Value = true;
    //        &amp;lt;Setter TargetName=&amp;quot;TB&amp;quot; Property=&amp;quot;Ellipse.Fill&amp;quot; Value=&amp;quot;Lightblue&amp;quot; /&amp;gt;
    Setter IMOSetter = new Setter(Ellipse.FillProperty, Brushes.LightBlue, &amp;quot;TB&amp;quot;);
    IMO.Setters.Add(IMOSetter);
    //    &amp;lt;/Trigger&amp;gt;
    ct.Triggers.Add(IMO);
    
    //    &amp;lt;Trigger Property=&amp;quot;IsPressed&amp;quot; Value=&amp;quot;true&amp;quot;&amp;gt;
    Trigger IP = new Trigger();
    IP.Property = Button.IsPressedProperty;
    IP.Value = true;
    //        &amp;lt;Setter TargetName=&amp;quot;TB&amp;quot; Property=&amp;quot;Ellipse.Fill&amp;quot; Value=&amp;quot;Blue&amp;quot; /&amp;gt;
    Setter IPSetter = new Setter(Ellipse.FillProperty, Brushes.Blue, &amp;quot;TB&amp;quot;);
    IP.Setters.Add(IPSetter);
    //    &amp;lt;/Trigger&amp;gt;
    ct.Triggers.Add(IP);
    
    //    &amp;lt;EventTrigger RoutedEvent=&amp;quot;ButtonBase.Click&amp;quot;&amp;gt;
    //http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.buttonbase.aspx
    EventTrigger BBC = new EventTrigger(System.Windows.Controls.Primitives.ButtonBase.ClickEvent);
    //        &amp;lt;EventTrigger.Actions&amp;gt;
    //            &amp;lt;BeginStoryboard Name=&amp;quot;playStoryboard&amp;quot; Storyboard=&amp;quot;{StaticResource playStoryboard}&amp;quot;/&amp;gt;
    BeginStoryboard BsPs = new BeginStoryboard();
    BsPs.Storyboard = (Storyboard)MyGrid.Resources[&amp;quot;playStoryboard&amp;quot;];
    BsPs.Name = &amp;quot;playStoryboard&amp;quot;;
    //        &amp;lt;/EventTrigger.Actions&amp;gt;
    BBC.Actions.Add(BsPs);
    //    &amp;lt;/EventTrigger&amp;gt;
    ct.Triggers.Add(BBC);
    //&amp;lt;/ControlTemplate.Triggers&amp;gt;
    &lt;/pre&gt;
&lt;p&gt;    [/update]&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-5196775716798705285?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/5196775716798705285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-6.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/5196775716798705285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/5196775716798705285'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-6.html' title='Calculator Demo -- Part 6'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-772962683184282908</id><published>2009-12-20T00:46:00.000-08:00</published><updated>2010-02-28T01:34:13.680-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='binding'/><category scheme='http://www.blogger.com/atom/ns#' term='content presenter'/><category scheme='http://www.blogger.com/atom/ns#' term='layout'/><category scheme='http://www.blogger.com/atom/ns#' term='method'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='frameworkelementfactory'/><category scheme='http://www.blogger.com/atom/ns#' term='grid'/><category scheme='http://www.blogger.com/atom/ns#' term='button'/><category scheme='http://www.blogger.com/atom/ns#' term='margin'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='templatedparent'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='compile'/><title type='text'>Calculator Demo — Part 5</title><content type='html'>&lt;p&gt;It took so much effort to style the buttons that I'm not going to do the animations until next time. Instead of playing around with the animations &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-4.html"&gt;like I said I would&lt;/a&gt;, I just made sure pressing the buttons would put the respective value into the display area.&lt;/p&gt;&lt;p&gt;I had to do a lot of research to translate the XAML for this part into C# so I will follow the same structure that I tried in &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-6.html"&gt;Alarm Clock Sample — Part 6&lt;/a&gt; (this time using the &lt;del&gt;&lt;a href="http://en.support.wordpress.com/code/posting-source-code/"&gt;sourcecode shortcode&lt;/a&gt;&lt;/del&gt; &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter"&gt;Syntax Highlighter&lt;/a&gt;).&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Defining the button style&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
&amp;lt;Style x:Key="DigitBtn"  TargetType="{x:Type Button}"&amp;gt;
&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush:csharp"&gt;
         Style DigitBtn = new Style();
         DigitBtn.TargetType = typeof(Button);&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;br /&gt;I simply looked up the &lt;a href="http://msdn.microsoft.com/en-us/library/ms753322.aspx"&gt;x:Type Markup Extension&lt;/a&gt; and followed my nose after reading "x:Type is essentially a markup extension equivalent for a typeof() operator in C#". Basically, this is telling the complier that the program will only be applying this style to Button objects.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Setting the "Focusable" property&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
&amp;lt;Setter Property="Focusable" Value="False"/&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
Setter setter1 = new Setter(Button.FocusableProperty, false);
DigitBtn.Setters.Add(setter1);&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;br /&gt;Since this is the first "Setter" I've seen, I needed to look up the &lt;a href="http://msdn.microsoft.com/en-us/library/ms587945.aspx"&gt;constructor&lt;/a&gt;. However, I still didn't understand what all this was for until I read &lt;a href="http://blogsprajeesh.blogspot.com/2009/03/wpf-data-binding-datatriggers.html"&gt;WPF Data Binding - DataTriggers&lt;/a&gt; though I only cared about the Data Binding part. It seems that because we are targeting buttons, we can set any properties that buttons have. This really makes me think of CSS classes because this program is going to have a bunch of buttons all with the same style so it makes sense to set up the style first and then, when you create the button element, you specify which style to use (similar to &lt;code&gt;&amp;lt;input type="button" value="Submit" class="DigitBtn"&amp;gt;&lt;/code&gt; for HTML+CSS).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Setting the "FontSize" property&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
&amp;lt;Setter Property="FontSize" Value="14pt"/&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
LengthConverter lc = new LengthConverter();
string qualifiedDouble = "14pt";
Setter setter2 = new Setter(Button.FontSizeProperty, lc.ConvertFrom(qualifiedDouble));
DigitBtn.Setters.Add(setter2);&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;br /&gt;Wow, so much work for something so simple. I would have never guessed this on my own...I know, I tried for quite a while. Thankfully, someone from the internets had &lt;a href="http://stackoverflow.com/questions/1279102/how-do-you-set-the-frameworkelement-width-property-to-the-value-of-a-qualifieddou"&gt;the answer&lt;/a&gt; (and a pretty good explanation).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Setting the "Margin" property&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
&amp;lt;Setter Property="Margin" Value="0"/&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
Setter setter3 = new Setter(Button.MarginProperty, new Thickness(0));
DigitBtn.Setters.Add(setter3);&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;br /&gt;Who would have guessed &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.margin.aspx"&gt;margins&lt;/a&gt; take values of &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.thickness.aspx"&gt;Thickness Structures&lt;/a&gt;? It makes sense now that I look closer. Instead of specifying that something has a left, top, bottom, and right margin you just say it has a margin and you define a margin to be something that has left, top, bottom, and right properties.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The final property "Template" is much more involved so I will describe what I did from the inside-out. Of course, I didn't deal with any animations or other triggers. I just wanted the buttons to show up and work.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Presenting the button's content&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
&amp;lt;ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
FrameworkElementFactory CP = new FrameworkElementFactory(typeof(ContentPresenter));
Binding TBinding = new Binding("Content"){RelativeSource = RelativeSource.TemplatedParent, Mode = BindingMode.OneWay};
CP.SetValue(ContentPresenter.ContentProperty, TBinding);
CP.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Center);
CP.SetValue(VerticalAlignmentProperty, VerticalAlignment.Center);&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;br /&gt;All of this gets nested inside a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx"&gt;ControlTemplate &lt;/a&gt;which was giving me a lot of problems because it doesn't work the same way as other containers (in C#--they all look the same in XAML). Fortunately, a quick Google search came up with &lt;a href="http://www.vistax64.com/avalon/23416-changing-drawing-style-button-code-c-c.html"&gt;Changing the drawing style of a button from code &lt;/a&gt; which introduced me to &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelementfactory.aspx"&gt;FrameworkElementFactory&lt;/a&gt;. I had to read two more sources of information to figure out &lt;code&gt;Content="{TemplateBinding Content}"&lt;/code&gt;: one, &lt;a href="http://msdn.microsoft.com/en-us/library/ms742882.aspx"&gt;TemplateBinding Markup Extension&lt;/a&gt;, told me that "A TemplateBinding is an optimized form of a Binding for template scenarios, analogous to a Binding constructed with {Binding RelativeSource={RelativeSource TemplatedParent} Mode=OneWay}."; two, &lt;a href="http://msdn.microsoft.com/en-us/library/ms742863.aspx"&gt;How to: Create a Binding in Code&lt;/a&gt;, had an extremely useful comment by LukeSkywalker (of all people). I tried running the code without the ContentPresenter and, lo and behold, the button's content, which holds the text, didn't show.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Styling the Button&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
&amp;lt;Ellipse Width="57" Height="49" x:Name="TB"  StrokeThickness="1" Stroke="{TemplateBinding Foreground}" Fill="{TemplateBinding Background}" HorizontalAlignment="Center" VerticalAlignment="Center" /&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
FrameworkElementFactory TB = new FrameworkElementFactory(typeof(Ellipse), "TB");
TB.SetValue(Ellipse.WidthProperty, 57.0);
TB.SetValue(Ellipse.HeightProperty, 49.0);
TB.SetValue(Ellipse.StrokeThicknessProperty, 1.0);
TB.SetValue(Ellipse.StrokeProperty, new Binding("Foreground") { RelativeSource = RelativeSource.TemplatedParent, Mode = BindingMode.OneWay });
TB.SetValue(Ellipse.FillProperty, new Binding("Background") { RelativeSource = RelativeSource.TemplatedParent, Mode = BindingMode.OneWay });
TB.SetValue(Ellipse.HorizontalAlignmentProperty, HorizontalAlignment.Center);
TB.SetValue(Ellipse.VerticalAlignmentProperty, VerticalAlignment.Center);&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;br /&gt;I quickly discovered, thanks to the compiler, that Height, Width and StrokeThickness need to have values of type Double so I simply added the decimal point to squash those errors. As for the bindings, this time I went for in-line declarations. I think that looks more organized.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Completing the Template setter&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
&amp;lt;Setter Property="Template"&amp;gt;
 &amp;lt;Setter.Value&amp;gt;
     &amp;lt;ControlTemplate TargetType="{x:Type Button}"&amp;gt;
         &amp;lt;Grid Width="60" Height="50"&amp;gt;
             ...
         &amp;lt;/Grid&amp;gt;
     &amp;lt;/ControlTemplate&amp;gt;
 &amp;lt;/Setter.Value&amp;gt;
&amp;lt;/Setter&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
Setter setter4 = new Setter();
setter4.Property = Button.TemplateProperty;

ControlTemplate ct = new ControlTemplate(typeof(Button));

FrameworkElementFactory grid = new FrameworkElementFactory(typeof(Grid));
grid.SetValue(Grid.WidthProperty, 60.0);
grid.SetValue(Grid.HeightProperty, 50.0);

...

grid.AppendChild(TB);
grid.AppendChild(CP);

ct.VisualTree = grid;

setter4.Value = ct;
DigitBtn.Setters.Add(setter4);&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;br /&gt;Because I was going to have to separate this setter's Value property, I used the empty constructor and then acted on the instance. Setting the setter's property property (that was fun to write) was as straight forward as the others. To set the setter's value property, I first created a ControlTemplate targeting a Button. Then I created a grid to hold the Ellipse and ContentPresenter. After instantiating the object to go into the grid, I discovered that I couldn't treat this grid object like I have before because it's actually a FrameworkElementFactory object. It was easy to find out how to add children to it though. Finally, thanks to &lt;a href="http://www.vistax64.com/avalon/23416-changing-drawing-style-button-code-c-c.html"&gt;Douglass Stockwell&lt;/a&gt;, I knew how to use VisualTree to complete the setter.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Adding the style to the main grid&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
&amp;lt;Grid.Resources &amp;gt;
 ...
 &amp;lt;/Style&amp;gt;
&amp;lt;/Grid.Resources&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
MyGrid.Resources.Add("DigitBtn", DigitBtn);&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;br /&gt;The style is defined inside the "Grid.Resources" tag so I added the style to MyGrid.Resources collection in the same way as adding the storyboard to the Window.Resources collection of the &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-6.html"&gt;Alarm Clock Sample&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Now that I got the style set up, I moved on to rendering the buttons. This part is just copy/paste once you get the first button to show. (In fact, I think it's so copy/paste that I might rewrite it using a loop.)&lt;/p&gt;&lt;p&gt;It was a little tricky for me because I haven't dealt with this level of customized UI before (at least with C#. I have done a complex GUI in Python with TkInter but TkInter's grid and pack managers are much less sophisticated).&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Initializing the grid&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
   &amp;lt;Grid.ColumnDefinitions&amp;gt;
     &amp;lt;ColumnDefinition/&amp;gt;
     ...
     &amp;lt;ColumnDefinition/&amp;gt;
   &amp;lt;/Grid.ColumnDefinitions&amp;gt;
   &amp;lt;Grid.RowDefinitions&amp;gt;
     &amp;lt;RowDefinition/&amp;gt;
     ...
     &amp;lt;RowDefinition/&amp;gt;
   &amp;lt;/Grid.RowDefinitions&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
...
MyGrid.RowDefinitions.Add(new RowDefinition());&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;br /&gt;I tried rendering a button without this and it just overlapped with the DisplayBox. The grid geometry manager in TkInter automatically creates the cells and I assumed WPF grids worked the same. I saw all this XAML which did nothing but create default objects and thought, &lt;em&gt;the code doesn't need this&lt;/em&gt;, but I was wrong. You explicitly have to create the rows and columns first, otherwise every visual object will overlap even if you've told the grid to put it somewhere else.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Creating the buttons&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
&amp;lt;Button Name="B7" Click="DigitBtn_Click" Style="{StaticResource DigitBtn}" Grid.Column="4" Grid.Row="2"&amp;gt;7&amp;lt;/Button&amp;gt;
...&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
Button B7 = new Button();
B7.Name = "B7";
B7.Click += new RoutedEventHandler(DigitBtn_Click);
B7.Style = MyGrid.Resources["DigitBtn"] as Style;
Grid.SetColumn(B7, 4);
Grid.SetRow(B7, 2);
B7.Content = "7";
MyGrid.Children.Add(B7);&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;br /&gt;It all made sense until the little "7" stuck between the tags. I looked up how to get the text for a button to show up and that led me to &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button%28VS.100%29.aspx"&gt;the wrong Button Class&lt;/a&gt;. It was telling me to set the Button.Text property but the compiler told me it doesn't exist. Someone else said, "&lt;a href="http://www.daniweb.com/forums/thread196582.html"&gt;WPF C# .text not working&lt;/a&gt;" and later said they were being an idiot because one should set the Button.Content property. I went back to the .NET Framework Class Library and discovered that I, too, was being an idiot because the correct place to look is &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.button.aspx"&gt;the System.Windows.Controls.Button Class&lt;/a&gt; which does, indeed, have a Button.Content property. Oh, and also note "as Style" when grabbing the Style resource. In the &lt;a href="http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-3.html"&gt;Alarm Clock Sample&lt;/a&gt;, the storyboard resource is grabbed with a cast &lt;code&gt;(Storyboard)clockWindow.Resources["clockHandStoryboard"]&lt;/code&gt;. The big difference between using a cast and using "as" is &lt;a href="http://msdn.microsoft.com/en-us/library/cscsdfbt.aspx"&gt;a cast will raise an exception but "as" will just yield null&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I then copied the DigitBtn_Click method into my Window1 class and now my unfinished calculator is at least looking much more finished. (I still don't know why they are converting the string into a character array instead of indexing the string itself...)&lt;/p&gt;&lt;p&gt;I planned on animating the buttons in this installment but just getting the buttons to render correctly was enough work for this time. I promise to do the animations next. I may even add in the operations.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-772962683184282908?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/772962683184282908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/it-took-so-much-effort-to-style-buttons.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/772962683184282908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/772962683184282908'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/it-took-so-much-effort-to-style-buttons.html' title='Calculator Demo — Part 5'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-7524236161575404075</id><published>2009-12-14T03:01:00.000-08:00</published><updated>2010-02-28T01:17:31.133-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='layout'/><category scheme='http://www.blogger.com/atom/ns#' term='conditional'/><category scheme='http://www.blogger.com/atom/ns#' term='TkInter'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='property'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='String.Empty'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='textbox'/><category scheme='http://www.blogger.com/atom/ns#' term='grid'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Calculator Demo -- Part 4</title><content type='html'>&lt;p&gt;After &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-3.html"&gt;getting the window working&lt;/a&gt;, I wanted some interaction. I looked at "ProcessKey()" to get started. I simply uncommented it in the "OnWindowKeyDown" method and then followed the code until there were no build errors.&lt;/p&gt;

&lt;p&gt;It's a very simple method as OOP recommends (I put in my own comments):&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;private void ProcessKey(char c)
        {
        &amp;nbsp;&amp;nbsp;if (EraseDisplay) //EraseDisplay is a property
        &amp;nbsp;&amp;nbsp;{
        &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Display = string.Empty; //Display is a property
        &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;EraseDisplay = false;
        &amp;nbsp;&amp;nbsp;}
        &amp;nbsp;&amp;nbsp;AddToDisplay(c);
        }&lt;/code&gt;&lt;/blockquote&gt;
        
&lt;p&gt;        This method first checks if we want to erase the display. (As commented, EraseDisplay and Display are properties of this class which I will look at next.) It then clears the Display property if need be and then calls a method to add the newly pressed character to the display.&lt;/p&gt;
        
&lt;p&gt;        Properties are a really cool feature of C#. &lt;a href="http://www.csharp-station.com/tutorials/Lesson10.aspx"&gt;This tutorial&lt;/a&gt; by &lt;a href="http://www.csharp-station.com/default.aspx"&gt;C# Station&lt;/a&gt; is a great introduction to how they can be used. Basically, they take away all the hassle of using getter/setter methods while still allowing you to customize how getting/setting is performed. The EraseDisplay and Display properties are as simple as you can get -- and they could easily be removed to use the naked variables "_erasediplay" [sic] and "_display" -- but, by structuring the code so that those variables be handled through properties allows for expansion such as validation or calling subroutines, etc.&lt;/p&gt;
        
&lt;p&gt;        Lastly, "AddToDisplay" is called. I think the programmer for this one wanted to make an example of nesting conditionals because it seems unnecessary (and I would have done it differently). Anyway, it starts by checking if a decimal point is already displayed. I've seen something like "IndexOf" in Python. It simply returns the index of the position in the string of the character you're looking for. String indexes start at 0 so if it returns a number greater than or equal to 0 then it does appear in the string and the method returns without changing the display (what number system uses more than one decimal point?) otherwise, it inserts the decimal point at the end. If the user presses a number the next conditional gets invoked which simply inserts the number at the end. If the user presses backspace, the final conditional is invoked which removes a single character from the end or sets the display to empty if there are no more characters to remove. Finally, and in any situation except the forced return, there is a call to "UpdateDisplay".&lt;/p&gt;
        
&lt;p&gt;        I'm definitely getting a better understanding of OOP principles. Each method above is focused on a single task and, if it needs to do something tangential to its core function, it calls upon another method to do that job. "ProcessKey" only exists to get the display ready before sending the character onto "AddToDisplay" which which does the work of altering the state of the display before calling "UpdateDisplay" which actually renders the new state.&lt;/p&gt;
        
&lt;p&gt;        The "UpdateDisplay" method warrants a closer look because it is so simple yet does so much (and there's a lot of interesting stuff to talk about):&lt;/p&gt;
        &lt;blockquote&gt;&lt;code&gt;        private void UpdateDisplay()
        {
        &amp;nbsp;&amp;nbsp;if (Display == String.Empty) //String.Empty vs Display.Length == 0
        &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DisplayBox.Text = "0"; //DisplayBox is of type MyTextBox initialized in the constructor
        &amp;nbsp;&amp;nbsp;else
        &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DisplayBox.Text = Display;
        }&lt;/code&gt;&lt;/blockquote&gt;
        
&lt;p&gt;        I say this method is simple because all it does is check if the display is empty and sets the text of "DisplayBox" (what the user sees) to 0 or to whatever value is in Display. I say it does so much because it makes use of a conditional, an interesting compare, and introduces a GUI element that it must alter.&lt;/p&gt;
        
&lt;p&gt;        Back when I was working on the &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-5.html"&gt;Alarm Clock Sample&lt;/a&gt;, I came across &lt;a href="http://www.tbiro.com/Check-empty-string-performance.htm"&gt;a website&lt;/a&gt; that compared String.Empty with Foo.Length tests. I found &lt;a href="http://dotnetperls.com/string-empty"&gt;another article&lt;/a&gt; which explains why the length test would work so much faster. I would like someone to explain why it is ever useful because I intend to never use it in my own code from now on.&lt;/p&gt;
        
&lt;p&gt;        Now for the GUI. I first noticed "DisplayBox" is an instance of the class "MyTextBox" which is defined in the file &lt;em&gt;mytextbox.cs&lt;/em&gt;. It inherits from "System.Windows.Controls.TextBox" and only overrides the "OnPreviewGotKeyboardFocus" event handler method and is being used exactly as &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.onpreviewgotkeyboardfocus.aspx"&gt;recommended&lt;/a&gt;: mark it as handled and then invoke the &lt;a href="http://msdn.microsoft.com/en-us/library/hfw7t1ce.aspx"&gt;base&lt;/a&gt; class implementation to keep the train rolling. Second, I saw that the "DisplayBox" instance is added to the layout by use of the Grid. The grid is setup with XAML so I stuck it in my "InitializeThis" method:&lt;/p&gt;
        
        
        &lt;blockquote&gt;&lt;code&gt;//&amp;lt;DockPanel Name="MyPanel"&amp;gt;
        MyPanel = new DockPanel();
        
        //
        MyGrid = new Grid();
        MyGrid.Name = "MyGrid";
        MyGrid.Background = Brushes.Wheat;
        MyGrid.ShowGridLines = false;
        
        //
        MyPanel.Children.Add(MyGrid);
        
        //
        this.Content = MyPanel;&lt;/code&gt;&lt;/blockquote&gt;
        
&lt;p&gt;        I declared each instance variable outside the methods and marked them as "static" because they are logically contained within the entire and every "window1" object. The rest of the code is a direct translation from XAML based on what I came to understand previously so I won't explain it further. However, I will explain my understanding of how "Grid" works. Again, I have to thank my Python experience for this. We tell the "DockPanel" that a Grid will manage the position and geometry of specified GUI objects (widgets). The Grid in .NET is much more sophisticated than TkInter in that you can specify many aspects of the Grid's display rather than simply indicate how it will manage geometry, and, you must specify which objects will be managed by the Grid. The content of the window is then set as the "DockPanel" so it knows what to render for viewing.&lt;/p&gt;
        
&lt;p&gt;        I will implement the button animations next to flesh out the GUI, play around with animations again, and get ready for implementing operations.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-7524236161575404075?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/7524236161575404075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-4.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/7524236161575404075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/7524236161575404075'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-4.html' title='Calculator Demo -- Part 4'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-1876635546802287106</id><published>2009-12-12T06:19:00.000-08:00</published><updated>2010-02-28T01:00:13.295-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='enum'/><category scheme='http://www.blogger.com/atom/ns#' term='enumeration'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='Main()'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='property'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='method'/><category scheme='http://www.blogger.com/atom/ns#' term='icon'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='if'/><category scheme='http://www.blogger.com/atom/ns#' term='select'/><title type='text'>Calculator Demo -- Part 3</title><content type='html'>&lt;p&gt;I have quite a lot going on now so I haven't been working on this much but I did get around to implementing the basic window for the Calculator. I did it in almost exactly the same way as the &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-5.html"&gt;Alarm Clock Sample&lt;/a&gt;. I created a file &lt;em&gt;myapp.cs&lt;/em&gt; and put in a Main() method, added a startup event handler, and then copied the rest of the file from the original version like so:&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;    public class app : Application
    {
    &amp;nbsp;&amp;nbsp;[STAThread]
    &amp;nbsp;&amp;nbsp;public static void Main()
    &amp;nbsp;&amp;nbsp;{
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app wpfcalculator = new app();
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wpfcalculator.Run();
    &amp;nbsp;&amp;nbsp;}
    
    &amp;nbsp;&amp;nbsp;app()
    &amp;nbsp;&amp;nbsp;{
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.Startup += new StartupEventHandler(AppStartingUp);
    &amp;nbsp;&amp;nbsp;}
    
    &amp;nbsp;&amp;nbsp;void AppStartingUp(object sender, StartupEventArgs e)
    &amp;nbsp;&amp;nbsp;{
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Window1 mainWindow = new Window1();
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mainWindow.Show();
    &amp;nbsp;&amp;nbsp;}
    }&lt;/code&gt;&lt;/blockquote&gt;
&lt;p&gt;    Then, I created a file &lt;em&gt;window1.cs&lt;/em&gt; to, at this point, write the corresponding C# code for the XAML:&lt;/p&gt;
    
    &lt;blockquote&gt;&lt;code&gt;&amp;lt;Window x:Class="WPFCalculator.Window1"
    &amp;nbsp;&amp;nbsp;xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    &amp;nbsp;&amp;nbsp;xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    &amp;nbsp;&amp;nbsp;Title="WPF Calculator"
    &amp;nbsp;&amp;nbsp;Height="400"
    &amp;nbsp;&amp;nbsp;Width="600" 
    &amp;nbsp;&amp;nbsp;ResizeMode="CanMinimize"  
    &amp;nbsp;&amp;nbsp;Icon="AppIcon.ico"
    &amp;nbsp;&amp;nbsp;TextInput="OnWindowKeyDown"
    &amp;gt;
    &lt;/code&gt;&lt;/blockquote&gt;
&lt;p&gt;    The difference this time being I created a method "InitializeThis()" which will contain all the translated XAML to correspond to "InitializeComponent()" which is normally used to parse XAML. So what I ended up with is:&lt;/p&gt;
    
    &lt;blockquote&gt;&lt;code&gt;        void InitializeThis()
    {
    &amp;nbsp;&amp;nbsp;this.Title = "WPF Calculator";
    &amp;nbsp;&amp;nbsp;this.Height = 400;
    &amp;nbsp;&amp;nbsp;this.Width = 600;
    &amp;nbsp;&amp;nbsp;this.ResizeMode = ResizeMode.CanMinimize;
    &amp;nbsp;&amp;nbsp;Uri iconUri = new Uri("appicon.ico", UriKind.Relative);
    &amp;nbsp;&amp;nbsp;this.Icon = System.Windows.Media.Imaging.BitmapFrame.Create(iconUri);
    &amp;nbsp;&amp;nbsp;this.TextInput += new System.Windows.Input.TextCompositionEventHandler(OnWindowKeyDown);
    }&lt;/code&gt;&lt;/blockquote&gt;
    
&lt;p&gt;    I think it's a good idea to take all that out of the constructor. The code will be much easier to follow.&lt;/p&gt;
    
&lt;p&gt;    I must be getting used to .NET after going through the Alarm Clock Sample because I didn't even blink when I wrote &lt;code&gt;this.ResizeMode = ResizeMode.CanMinimize;&lt;/code&gt;--it just seemed right that "ResizeMode" must be set to a certain value which would be enumerated and encapsulated in the "ResizeMode" object/method [update: looks more like its overloaded to be both an Enum object and a Property] itself. I also had a feeling that something like &lt;del datetime="2009-12-12T11:49:23+00:00"&gt;&lt;code&gt;this.Icon = "appicon.ico"&lt;/code&gt;&lt;/del&gt; wouldn't work so I looked up the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.window.icon.aspx"&gt;Window.Icon Property&lt;/a&gt;. The example given there, however, assumes that the icon resource is compiled along with the application but I wanted to use an external file so I just used the same idea as the window image used in the &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-5.html"&gt;Alarm Clock Sample&lt;/a&gt;. The TextInput event handler code wrote itself using Visual Studio but I understand it. &lt;/p&gt;
    
&lt;p&gt;    As for "OnWindowKeyDown", I simply copied it. I don't like to just copy and paste when I'm learning so I typed it out. Of course, I didn't want to rewrite the whole program in one go so I didn't copy method calls:&lt;/p&gt;
    
    &lt;blockquote&gt;&lt;code&gt;        private void OnWindowKeyDown(object sender, System.Windows.Input.TextCompositionEventArgs e)
    {
    &amp;nbsp;&amp;nbsp;string s = e.Text;
    &amp;nbsp;&amp;nbsp;char c = (s.ToCharArray())[0];
    &amp;nbsp;&amp;nbsp;e.Handled = true;
    
    &amp;nbsp;&amp;nbsp;if ((c &amp;gt;= '0' &amp;amp;&amp;amp; c &amp;lt;= &amp;#39;9&amp;#39;) || c == &amp;#39;.&amp;#39; || c == &amp;#39;\b&amp;#39;)  // &amp;#39;\b&amp;#39; is backspace
    &amp;nbsp;&amp;nbsp;{
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return;
    &amp;nbsp;&amp;nbsp;}
    
    &amp;nbsp;&amp;nbsp;switch (c)
    &amp;nbsp;&amp;nbsp;{
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case &amp;#39;+&amp;#39;:
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case &amp;#39;-&amp;#39;:
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case &amp;#39;*&amp;#39;:
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case &amp;#39;/&amp;#39;:
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case &amp;#39;%&amp;#39;:
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case &amp;#39;=&amp;#39;:
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
    &amp;nbsp;&amp;nbsp;}
    }
    &lt;/code&gt;&lt;/blockquote&gt;
    
&lt;p&gt;    There's some interesting stuff there about C#, .NET, and programming practice.&lt;/p&gt;
    
&lt;p&gt;    As in the &lt;a href="http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-1.html"&gt;Alarm Clock Sample&lt;/a&gt;, event handlers need to accept certain arguments and, because C# is strongly typed, they need to accept very specific arguments. Here, an event object of type "&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.textcompositioneventargs.aspx"&gt;System.Windows.Input.TextCompositionEventArgs&lt;/a&gt;" is accepted and that holds interesting information in its "Text" member. If any key is pressed we just want the first character of that key's associated sequence so that's what is copied into a variable and then we don't care about the event anymore so flag it as "handled". (I thought I read that strings can be indexed to retrieve characters so I tried changing the code to simply &lt;code&gt;char c = e.Text[0];&lt;/code&gt; and there was no problem compiling. I'm not sure why Microsoft wrote it differently but perhaps it's because of &lt;a href="http://msdn.microsoft.com/en-us/library/ezftk57x.aspx"&gt;how&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/system.char.aspx"&gt;unicode&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/system.string.aspx"&gt;works&lt;/a&gt;.)&lt;/p&gt;
    
&lt;p&gt;    The use of "if" and "switch" blocks is the most fun part of this method. The keys which would be used to update the display (numerical, the decimal point, and backspace) are all handled similarly and they are used the most so they are checked simultaneously by the "if" statement before anything else. Note &lt;code&gt;(c &amp;gt;= '0' &amp;amp;&amp;amp; c &amp;lt;= &amp;#39;9&amp;#39;)&lt;/code&gt; shows that characters can be ordered in C# (ASCII FTW).The operation characters are then checked by a "switch" statement. This makes sense because they each have a very different function, and it just looks better than "if (c == '+' || c == '-' || ... || c == '=')" especially if you're going to add more (key binded) operations later.&lt;/p&gt;
    
&lt;p&gt;    Next, I think I will check out "ProcessKey()" and however you get those keys to display.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-1876635546802287106?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/1876635546802287106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/1876635546802287106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/1876635546802287106'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-3.html' title='Calculator Demo -- Part 3'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-2602837920112538698</id><published>2009-12-09T21:32:00.000-08:00</published><updated>2010-02-23T06:15:01.178-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='layout'/><category scheme='http://www.blogger.com/atom/ns#' term='animation'/><category scheme='http://www.blogger.com/atom/ns#' term='textblock'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='textbox'/><category scheme='http://www.blogger.com/atom/ns#' term='grid'/><category scheme='http://www.blogger.com/atom/ns#' term='button'/><title type='text'>Calculator Demo — Part 2</title><content type='html'>&lt;p&gt;By &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-6.html"&gt;completing&lt;/a&gt; the Alarm Clock Sample, I got a pretty good understanding of how to program Windows Presentation Foundation using only C# and how XAML files are related to the .NET Class Library.&lt;/p&gt;

&lt;p&gt;The calculator demo is a lot less intimidating now so I want to go back to it. Again, I will try to implement it using only C#. Translating the XAML into C# will still be difficult because of the heavily nested code seen in &lt;em&gt;window1.xaml&lt;/em&gt; but it should be much easier now that I understand the syntax much more clearly. More interestingly, there is a lot of C# already used for the code-behind. In fact, there's more C# than XAML so I'm hoping that what I learn from this project will be more relevant to the subject of this blog.&lt;/p&gt;

&lt;p&gt;I'm assuming I don't need to look at &lt;em&gt;resources.cs&lt;/em&gt;, &lt;em&gt;resources.res&lt;/em&gt;x, &lt;em&gt;settings.cs&lt;/em&gt;, or &lt;em&gt;settings.settings&lt;/em&gt; because they were useless in porting the Alarm Clock Sample. I fully understand what's going on in &lt;em&gt;app.xaml&lt;/em&gt; and &lt;em&gt;app.xaml.cs&lt;/em&gt; thanks to &lt;a href="http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-1.html"&gt;my earlier research&lt;/a&gt;. A new "window1" object is instantiated on startup. It is defined by &lt;em&gt;window1.xaml&lt;/em&gt; and &lt;em&gt;window1.xaml.cs&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Immediately, I notice that &lt;em&gt;window1.xaml&lt;/em&gt; is heavy on buttons and grid. Grid must be a kind of layout manager (in &lt;a href="http://wiki.python.org/moin/TkInter"&gt;Tkinter&lt;/a&gt; for &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; there is also a grid geometry manager and they probably work similarly). It will be very worthwhile to come to an understanding about layout. There's also a little bit about a menu (which is also useful to learn), simpler animation than the Alarm Clock Sample, and one instance of a TextBlock. My initial perusal has convinced me that a "TextBlock" is not the same as a "TextBox".&lt;/p&gt;

&lt;p&gt;There is a definition of class called MyTextBox in &lt;em&gt;mytextbox.cs&lt;/em&gt; which inherits from the TextBox class and the only purpose seems to be to override a specific eventhandler: &lt;code&gt;OnPreviewGotKeyboardFocus&lt;/code&gt;. I'll figure the reason in the next installment but, for now, I'm satisfied with knowing it's used in &lt;em&gt;window1.xaml.cs&lt;/em&gt; along with the really interesting looking PaperTrail class.&lt;/p&gt;

&lt;p&gt;As I mentioned before, &lt;em&gt;window1.xaml.cs&lt;/em&gt; has a lot of program logic in it so I think it will be fun to go through to try to understand.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-2602837920112538698?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/2602837920112538698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/2602837920112538698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/2602837920112538698'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/calculator-demo-part-2.html' title='Calculator Demo — Part 2'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-5578669378393820946</id><published>2009-12-08T22:54:00.000-08:00</published><updated>2010-02-23T05:10:30.370-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='storyboard'/><category scheme='http://www.blogger.com/atom/ns#' term='name scope'/><category scheme='http://www.blogger.com/atom/ns#' term='method'/><category scheme='http://www.blogger.com/atom/ns#' term='paralleltimeline'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='cpu'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='animation'/><category scheme='http://www.blogger.com/atom/ns#' term='property'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='compile'/><title type='text'>Alarm Clock Sample -- Part 6</title><content type='html'>&lt;p&gt;The most annoying part of losing the XAML was making the animations work. Looking back, it seems pretty simple but getting there led me to a lot of frustration.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.resources.aspx"&gt;Every framework element has a resources property&lt;/a&gt; but that page doesn't get into detail about using the resource property without XAML. I had to figure it out from other code. After &lt;code&gt;&amp;lt;Window.Resources&amp;gt;&lt;/code&gt; in &lt;em&gt;traditionalclock.xaml&lt;/em&gt;, you come across &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.animation.storyboard.aspx"&gt;the Storyboard Class&lt;/a&gt;, the website for which offers a good example of using it in C# but does not mention &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.animation.paralleltimeline.aspx"&gt;the ParallelTimeline Class&lt;/a&gt; which is used next in the file. Again, the documentation from Microsoft offers no help about using it without XAML. &lt;/p&gt;

&lt;p&gt;The tutorial &lt;a href="http://www.codeproject.com/KB/WPF/WPFParticleEffects.aspx"&gt;Particle Effects in WPF&lt;/a&gt; was very helpful in showing me that you must add animation types to the ParallelTimeline by registering them as children of the ParallelTimeline. However, I still wasn't able to get the animation working (I was either getting no build errors with the no animation or build errors that told me I didn't yet know what I was doing. It wasn't until I came across a much more &lt;a href="http://msdn.microsoft.com/en-us/library/ms752357.aspx"&gt;advanced animation example&lt;/a&gt; when I finally understood everything I was doing wrong and what I needed to do right. (Now, that I look at that example again, I see it comes from &lt;a href="http://msdn.microsoft.com/en-us/library/ms749238.aspx"&gt;a set of very nice examples&lt;/a&gt; which give pure C# representations alongside XAML + C# code-behind).&lt;/p&gt;

&lt;p&gt;Anyway, here's the play-by-play:&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;Setting up the Storyboard
    &lt;ul&gt;
    &lt;li&gt;XAML:
    &lt;pre class="brush: xml"&gt;
        &amp;lt;Window.Resources&amp;gt;
        &amp;lt;Storyboard x:Key="clockHandStoryboard"&amp;gt;
        &amp;lt;ParallelTimeline&amp;gt;
        &amp;lt;DoubleAnimation From="-9" To="351" Duration="00:01:00" RepeatBehavior="Forever" Storyboard.TargetProperty="Angle" Storyboard.TargetName="secondHandAngle"/&amp;gt;
        ...[other DoubleAnimation code is similar]...
        &amp;lt;/ParallelTimeline&amp;gt;
        &amp;lt;/Storyboard&amp;gt;
        &amp;lt;/Window.Resources&amp;gt;
    &lt;/pre&gt; 
    &lt;/li&gt;
    &lt;li&gt;C#:
    &lt;pre class="brush: csharp"&gt;
        NameScope.SetNameScope(this, new NameScope());
        Storyboard clockHandStoryboard = new Storyboard();
        ParallelTimeline pt = new ParallelTimeline(TimeSpan.FromSeconds(0));
        DoubleAnimation secondHandAnimation = new DoubleAnimation(-9, 351, new Duration(new TimeSpan(0, 1, 0)));
        Storyboard.SetTargetName(secondHandAnimation, "secondHandAngle");
        Storyboard.SetTargetProperty(secondHandAnimation, new PropertyPath(RotateTransform.AngleProperty));
        secondHandAnimation.RepeatBehavior = RepeatBehavior.Forever;
        ...
        pt.Children.Add(secondHandAnimation);
        ...
        clockHandStoryboard.Children.Add(pt);
        
        this.Resources.Add("clockHandStoryboard", clockHandStoryboard);
        this.RegisterName("clockHandStoryboard", clockHandStoryboard);
    &lt;/pre&gt;
    &lt;/li&gt;
    &lt;li&gt;Notes:&lt;br /&gt;
    A name scope is created for the window so that we can later register the storyboard and animation target names with the scope. A storyboard and ParallelTimeline are then instantiated to hold the animation information. Notice that to create the DoubleAnimation in C#, several steps are used whereas in XAML it is one line. "SetTargetName" specifies a string which is the name of the object, in the name scope, to be animated. Once the animations were set-up, I added them to the ParallelTimeline, then added the ParallelTimeline to the Storyboard. Finally, I added the Storyboard to the window's Resources collection since that's how it was outlined in XAML and then added its name to the name scope since that's what Microsoft suggested.&lt;/li&gt;
    &lt;/ul&gt;
 &lt;/li&gt;
 &lt;li&gt;Triggering the Animation (this is the same for each hand)
    &lt;ul&gt;
    &lt;li&gt;XAML:
    &lt;pre class="brush: xml"&gt;
        &amp;lt;Canvas.Triggers&amp;gt;
        &amp;lt;EventTrigger RoutedEvent="Canvas.Loaded"&amp;gt;
        &amp;lt;EventTrigger.Actions&amp;gt;
        &amp;lt;BeginStoryboard Name ="clockHandStoryboard" Storyboard="{StaticResource clockHandStoryboard}" /&amp;gt;
        &amp;lt;/EventTrigger.Actions&amp;gt;
        &amp;lt;/EventTrigger&amp;gt;
        &amp;lt;/Canvas.Triggers&amp;gt;
    &lt;/pre&gt;
    &lt;/li&gt;
    &lt;li&gt;C#:
    &lt;pre class="brush: csharp"&gt;
        EventTrigger canvasTrigger = new EventTrigger();
        canvasTrigger.RoutedEvent = Canvas.LoadedEvent;
        BeginStoryboard beginStory = new BeginStoryboard();
        beginStory.Name = "clockHandStoryboard";
        beginStory.Storyboard = clockHandStoryboard;
        canvasTrigger.Actions.Add(beginStory);
        clockCanvas.Triggers.Add(canvasTrigger);
    &lt;/pre&gt;
    &lt;/li&gt;
    &lt;li&gt;Notes:&lt;br /&gt;
    With each step towards understanding, this is getting easier and easier. Again, I noticed that the XAML and C# don't correspond exactly but it's easy for me to see now that "Canvas.Triggers" and "EventTrigger.Actions" must be some kind of collection so I immediately check for an "Add" method or "Children.Add" method.&lt;/li&gt;
    &lt;/ul&gt;
 &lt;/li&gt;
 &lt;li&gt;Registering the animation
    &lt;ul&gt; 
    &lt;li&gt;XAML:
    &lt;pre class="brush: xml"&gt;
        &amp;lt;Polygon.RenderTransform&amp;gt;
        &amp;lt;RotateTransform x:Name="hourHandAngle" CenterX="4" CenterY="45" /&amp;gt;
        &amp;lt;/Polygon.RenderTransform&amp;gt;
    &lt;/pre&gt;
    &lt;/li&gt;
    &lt;li&gt;C#:
    &lt;pre class="brush: csharp"&gt;
        RotateTransform hourHandAngle = new RotateTransform();
        this.RegisterName("hourHandAngle", hourHandAngle);
        hourHandAngle.CenterX = 4;
        hourHandAngle.CenterY = 45;
        hourHand.RenderTransform = hourHandAngle;
    &lt;/pre&gt;
    &lt;/li&gt;
    &lt;li&gt;Notes:&lt;br /&gt;
    It took me far too long to discover that you must register the transform's name. I had assumed that "x:Name" meant the transform had a "Name" property but it doesn't so I spent a long time trying different things before I looked it up in the various sources mentioned above. I don't want to rely on external sources, I want to try to figure it out myself through debugging but when you really don't understand, it's best to look it up instead of wasting time.
    &lt;/li&gt;
    &lt;/ul&gt;
 &lt;/li&gt;
    &lt;/ul&gt;
    
&lt;p&gt;The pure C# clock finally works. There is no need to change &lt;em&gt;assemblyinfo.cs&lt;/em&gt; if you want to add that information into the properties dialogue. The executable of the port is significantly smaller than the original. I guess that's because it doesn't need to hold any of the XAML information (though I would expect it to all be parsed and compiled similarly to my rewrite). Also, the original build and my new one are clearly using methods supported by Microsoft, I would have expected them to create an animation library that doesn't consume 50% cpu when looping forever. If there's another way besides "RepeatBehavior="Forever" I'd really like to know.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-5578669378393820946?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/5578669378393820946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-6.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/5578669378393820946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/5578669378393820946'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-6.html' title='Alarm Clock Sample -- Part 6'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-7186899162628833563</id><published>2009-12-07T01:57:00.000-08:00</published><updated>2010-02-23T04:16:37.133-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='image'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='Main()'/><category scheme='http://www.blogger.com/atom/ns#' term='LinearGradientBrush'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='property'/><category scheme='http://www.blogger.com/atom/ns#' term='polygon'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='canvas'/><title type='text'>Alarm Clock Sample — Part 5</title><content type='html'>&lt;p&gt;I &lt;a href="http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-4.html"&gt;left off&lt;/a&gt; saying, I would "rewrite the Alarm Clock Sample in pure C# without help from XAML". This turned out to be much more difficult than expected. XAML hides a lot of complexity so about 80% of the time it took to rewrite it was spent looking up references and examples in the .NET Class Framework Library and other sources. It seems WPF was developed with XAML in mind and so the amount of resources which explain how to use it with C# are severely lacking. I put the source on &lt;a href="http://github.com/piannaf/Alarm-Clock"&gt;my github account&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Firstly, every C# program must have a Main() method as an entry point. I added one to a new &lt;em&gt;myapp.cs&lt;/em&gt; (without the "partial" modifier for the class definition) and tried to compile. It wouldn't. For some reason it was complaining about missing references but I put in the correct "using" statements and even tried copying and pasting code that was supposed to work from both Microsoft and &lt;a href="http://www.tbiro.com/Hello-WPF-Without-XAML.htm"&gt;Hello WPF (without XAML)&lt;/a&gt;. I commented out the body of the "AppStartup" method since I didn't care about actually getting the clock to work. I just wanted to start the application. Eventually, I found &lt;a href="http://msdn.microsoft.com/en-us/library/aa970678.aspx#Building_a_WPF_Application_using_Command_Line"&gt;Building a WPF Application by Using Command-Line Compilation&lt;/a&gt; which shows there are three references which do not get added by default and must be available for WPF applications. I didn't feel like typing all that in so I fired up Visual Studio and added those references. Sure enough, it compiled and ran (but could only be seen in the task manager of course).&lt;/p&gt;&lt;p&gt;Second, I created &lt;em&gt;traditionalclock.cs&lt;/em&gt; so I could get at least the clock image to show in a transparent window. I copied &lt;em&gt;traditionalclock.xaml.cs&lt;/em&gt; and commented everything except the constructor. From &lt;a href="http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-3.html"&gt;part 3&lt;/a&gt;, I knew that &lt;code&gt;InitializeComponent();&lt;/code&gt; was for parsing the relevant XAML so I removed it and began to look at &lt;em&gt;traditionalclock.xaml&lt;/em&gt;.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Rendering the window&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="clockWindow"
AllowsTransparency="true"
Background="Transparent"
WindowStyle="None"
MouseLeftButtonDown="LeftButtonDown"
&amp;gt;...&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
    this.Name = "clockWindow";
    this.AllowsTransparency=true;
    this.Background=Brushes.Transparent;
    this.WindowStyle=WindowStyle.None;
    this.MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(this.LeftButtonDown);&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;p&gt;This was the easiest code to implement because the XAML code is nearly in one-to-one correspondence to the required C# code. Notice the "MouseButtonEventHandler" comes from a different namespace than all the "using" statements.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Rendering the image&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
    &amp;lt;Canvas Name="clockCanvas" Width="292" Height="493"  &amp;gt;
    ...
    &amp;lt;Image Source="TradClock.png" Loaded="SetTime" /&amp;gt;
    ...
    &amp;lt;/Canvas&amp;gt;&lt;/pre&gt;&lt;/li&gt;
    &lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;using System.Windows.Media.Imaging;
    ...
    Canvas clockCanvas = new Canvas();
    ...
    clockCanvas.Name = "clockCanvas";
    clockCanvas.Width = 292;
    clockCanvas.Height = 493;
    ...
    Image tradClock = new Image(); 
    BitmapImage bi3 = new BitmapImage();
    bi3.BeginInit();
    bi3.UriSource = new Uri("TradClock.png", UriKind.Relative);
    bi3.EndInit();
    tradClock.Source = bi3;
    tradClock.Loaded += new RoutedEventHandler(this.SetTime);
    clockCanvas.Children.Add(tradClock);
    ...
    this.Content = clockCanvas;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;p&gt;I initialized "clockCanvas" as a class variable so that it could be referenced outside the contructor. Setting properties of the canvas was quite simple by looking at the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas.aspx"&gt;Canvas Class documentation&lt;/a&gt; but placing the image onto the canvas was more difficult. The XAML makes it look like you can just create a new instance of an Image and then set the source to be the file. It's not as straight forward as that but, fortunately, &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.image.source.aspx"&gt;Image.Source Property&lt;/a&gt; gives some helpful details. It doesn't, however, tell you you must include the System.Windows.Media.Imaging namespace. Lastly, notice the image must be made a child of the canvas and the canvas must be put into the window's content. This is analogous to nesting the tags in XAML.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;When I was porting the XAML over to C#, I actually just started from the top and continued downward. But that wasn't good for two reasons: one, the animations require targets which wouldn't be created until towards the end; two, since I didn't understand how everything fit together, when there were errors it was difficult to figure out what was going wrong. Above are the parts which I didn't have to comment out when I decided I should just try to get the clock to show up. Once I finished the above, the image appeared in a transparent window and I was able to continue. Since getting the image to render was much more involved than the XAML led me to believe, I set out to get the hands of the clock to render before trying the animation. (Each hand is basically the same, so I will only consider the hour hand)&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Initializing the clock hands (make the shape)&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
    &amp;lt;"hourHand" Canvas.Top="214" Canvas.Left="173" Points="0,5 3,0 4,0 8,5 8,50 0,50"&amp;gt;...&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
    Polygon hourHand = new Polygon();
    Point hPoint1 = new Point(0, 5);
    Point hPoint2 = new Point(3, 0);
    Point hPoint3 = new Point(4, 0);
    Point hPoint4 = new Point(8, 5);
    Point hPoint5 = new Point(8, 50);
    Point hPoint6 = new Point(0, 50);
    PointCollection myPointCollection = new PointCollection();
    myPointCollection.Add(hPoint1);
    myPointCollection.Add(hPoint2);
    myPointCollection.Add(hPoint3);
    myPointCollection.Add(hPoint4);
    myPointCollection.Add(hPoint5);
    myPointCollection.Add(hPoint6);
    hourHand.Points = myPointCollection;
    ...
    hourHand.Name = "hourHand";
    ...
    Canvas.SetTop(hourHand, 214);
    Canvas.SetLeft(hourHand, 173);
    clockCanvas.Children.Add(hourHand);&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;p&gt;I wasn't sure how to get that list of points to become a property of the Polygon shape. Visual Studio was telling me "Polygon.Points" required a collection of points but did that mean an array or some other kind of object? Luckily, there is a great example at the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.shapes.polygon.points.aspx"&gt;Polygon.Points Property&lt;/a&gt; reference. It is possible, and more traditional, to make an array of points which you can iterate over to add each point to the collection in turn:&lt;pre class="brush: csharp"&gt;
    Point[] hPoints = new Point[6] { new Point(0, 5), new Point(3, 0), new Point(4, 0), 
    new Point(8, 5), new Point(8, 50), new Point(0, 50)};
    PointCollection myPointCollection = new PointCollection();
    foreach (Point p in hPoints){
    myPointCollection.Add(p);
    }&lt;/pre&gt;and, even better, there's a overload of the "PointCollection" constructor which takes an iterable collection of points to automatically add them so you can just write &lt;code&gt;PointCollection myPointCollection = new PointCollection(hPoints);&lt;/code&gt; without writing the loop. I just did each point explicitly to stay true to the example Microsoft gives in the documentation.&lt;br /&gt;XAML was misleading again with "Canvas.Top" and "Canvas.Left" but the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas.top.aspx"&gt;documentation&lt;/a&gt; cleared everything up for me.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;li&gt;Rendering the clock hands (make it visible)&lt;ul&gt;&lt;li&gt;XAML:&lt;pre class="brush: xml"&gt;
    &amp;lt;polygon.fill&amp;gt;
    &amp;lt;LinearGradientBrush StartPoint="0,0" EndPoint="1,0"&amp;gt;
    &amp;lt;lineargradientbrush.gradientstops&amp;gt;
    &amp;lt;gradientstop offset="0" color="White"&amp;gt;&amp;lt;/gradientstop&amp;gt;
    &amp;lt;gradientstop offset=&amp;quot;1&amp;quot; color=&amp;quot;DarkGray&amp;quot;&amp;gt;&amp;lt;/gradientstop&amp;gt;
    &amp;lt;/lineargradientbrush.gradientstops&amp;gt;
    &amp;lt;/polygon.fill&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;C#:&lt;pre class="brush: csharp"&gt;
    LinearGradientBrush hourHandBrush = new LinearGradientBrush();
    hourHandBrush.StartPoint = new Point(0, 0);
    hourHandBrush.EndPoint = new Point(1, 0);
    hourHandBrush.GradientStops.Add(new GradientStop(Colors.White, 0));
    hourHandBrush.GradientStops.Add(new GradientStop(Colors.DarkGray, 1));
    hourHand.Fill = hourHandBrush;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Notes:&lt;p&gt;I looked at the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.shapes.shape.fill.aspx"&gt;Shape.Fill Property&lt;/a&gt; first because that is what is first in XAML. It gave me a good starting point because I noticed they created a new instance of a "SolidColorBrush", set the properties of the brush and then set the brush as the fill property. All, I had to do was look up how to instantiate the properties of a new &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.lineargradientbrush.aspx"&gt;LinearGradientBrush&lt;/a&gt; and then follow the example.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The "&amp;lt;!--Center circles--&amp;gt;" were extremely easy once I got all the hands set up. In the next part, I will show how I got the animations going.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-7186899162628833563?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/7186899162628833563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-5.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/7186899162628833563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/7186899162628833563'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-5.html' title='Alarm Clock Sample — Part 5'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-2995811593480632273</id><published>2009-12-01T20:41:00.000-08:00</published><updated>2010-02-23T03:39:54.167-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Resource Designer'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='preprocessor'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Alarm Clock Sample -- Part 4</title><content type='html'>&lt;p&gt;Parts &lt;a href="http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-1.html"&gt;1&lt;/a&gt;, &lt;a href="http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-2.html"&gt;2&lt;/a&gt;, &lt;a href="http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-3.html"&gt;3&lt;/a&gt; described my steps to understanding the Alarm Clock Sample program but there are still a few files left many of which may have been autogenerated.&lt;/p&gt;&lt;p&gt;In no particular order:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;assemblyinfo.cs&lt;/em&gt;&lt;br /&gt;An assembly is a compiled file in .NET nomenclature so I assume this file will describe information about the final output file. There are &lt;a href="http://msdn.microsoft.com/en-au/library/ed8yd1ha(VS.71).aspx"&gt;preprocessor directives&lt;/a&gt; in this file, I haven't seen them in any other file so far and that makes me think this file was autogenerated (also note the detail and amount of comments). &lt;code&gt;#region&lt;/code&gt; has nothing to do with application logic, it's just for editor eyecandy.&lt;br /&gt;Code in the square brackets looked familiar to me. If you right click on an executable or dll, in the properties dialogue, this code sets up what you will see in the version tab (maybe the summary tab too). Some of the fields don't match though, I changed &lt;code&gt;AssemblyDescription&lt;/code&gt; and it was shown in the value of the "Comments" item. Of course the .NET Framework Class Library has all that information in the &lt;a href="http://msdn.microsoft.com/en-au/library/system.reflection.aspx"&gt;System.Reflection Namespace&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;em&gt;resources.designer.cs&lt;/em&gt;&lt;br /&gt;This file states upfront that it is autogenerated. It is the "Resource Designer" that generates the file. From the &lt;a href="http://msdn.microsoft.com/en-us/library/t69a74ty.aspx"&gt;Visual Studio Reference&lt;/a&gt;&lt;/p&gt;&lt;blockquote&gt;The Resource Designer is a user interface tool that enables you to manage resources (such as strings, images, icons, audio, and other files) for your project. .... Items that you add to the project by using the Resource Designer are placed in the Resources directory for your project. The designer information is stored in a file named Resources.resx, and code for the resource is stored in Resources.Designer.cs....&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;resources.resx&lt;/em&gt;&lt;br /&gt;From the above, we know "the designer information is stored here". But that doesn't really help me understand the file. &lt;a href="http://www.c-sharpcorner.com/UploadFile/yougerthen/105032008041615AM/1.aspx"&gt;Bechir Bejaoui gives a nice, quick introduction&lt;/a&gt;. It looks like these files are not something you would want to write yourself. I guess it would be best to use Visual Studio to generate these if you are going to have a ton of external resources and you want to keep track of them in this way.&lt;/li&gt;&lt;li&gt;&lt;em&gt;settings.designer.cs&lt;/em&gt; and &lt;em&gt;settings.settings&lt;/em&gt;&lt;br /&gt;I couldn't find much information about these two files to help me understand them so I'm putting them together. The best thing I could find was from the &lt;a href="http://msdn.microsoft.com/en-us/library/a65txexh.aspx"&gt;Visual Studio Reference &lt;/a&gt;. My understanding is that you can use these two files to set up a way to allow changeable but persistent application settings. The user can change some setting in the program and then when they close and reopen it, the settings will still be there. Seems to be a new fangled *.ini file.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The next thing I'm going to do to improve my understanding of C# is rewrite the Alarm Clock Sample in pure C# without help from XAML (I'll try to understand XAML more fully in the future).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-2995811593480632273?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/2995811593480632273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-4.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/2995811593480632273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/2995811593480632273'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/12/alarm-clock-sample-part-4.html' title='Alarm Clock Sample -- Part 4'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-1647378450570603199</id><published>2009-11-30T04:39:00.000-08:00</published><updated>2010-02-23T03:26:50.393-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='class'/><category scheme='http://www.blogger.com/atom/ns#' term='namespace'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='property'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='method'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Alarm Clock Sample -- Part 3</title><content type='html'>&lt;p&gt;&lt;a href="http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-2.html"&gt;Last time&lt;/a&gt; I mentioned, "There’s an object TraditionalClock defined somewhere", so in this post I want to look closely at how the TraditionalClock object is created.&lt;/p&gt;&lt;p&gt;I supposed that &lt;em&gt;traditionalclock.xaml&lt;/em&gt; and &lt;em&gt;traditionalclock.xaml.cs&lt;/em&gt; probably hold the key and I'll start with &lt;em&gt;traditionalclock.xaml&lt;/em&gt;. The first line is &lt;code&gt;&amp;lt;Window x:Class=&amp;quot;Microsoft.Samples.WinFX.AlarmClock.TraditionalClock&amp;quot;&lt;/code&gt; so I checked out the &lt;a href="http://msdn.microsoft.com/en-us/library/ms753327.aspx"&gt;XAML Namespace (x:) Language Features&lt;/a&gt; which led me to&lt;/p&gt;&lt;blockquote&gt;Configures XAML compilation to join partial classes between markup and code-behind. The code partial class is defined in a separate code file in a Common Language Specification (CLS) language, whereas the markup partial class is created by code generation during XAML compilation.&lt;/blockquote&gt;&lt;p&gt;From this description, I deduced that&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Window&lt;/strong&gt; is the parent of the class that's going to be defined&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Microsoft.Samples.WinFX.AlarmClock.TraditionalClock&lt;/strong&gt; indicates the name of the class will be "TraditionalClock" in the Microsoft.Samples.WinFX.AlarmClock namespace&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;And, actually, looking in &lt;em&gt;traditionalclock.xaml.cs&lt;/em&gt;, that deduction, translated into C# exists exactly. Note especially that it's a partial class in C# since from the "x:Class Attribute" we know that when the XAML is compiled a partial class of the same name will be created.&lt;/p&gt;&lt;p&gt;This made me think I could understand &lt;em&gt;myapp.xaml&lt;/em&gt; and &lt;em&gt;myapp.xaml.cs&lt;/em&gt; a little better too. Going to &lt;em&gt;myapp.xaml&lt;/em&gt;, I noticed &lt;code&gt;&amp;lt;Application x:Class=&amp;quot;Microsoft.Samples.WinFX.AlarmClock.MyApp&amp;quot;&lt;/code&gt; which makes sense now as it will create a partial class MyApp in the correct namespace inheriting from the WPF Application object which is exactly what we came to understand about &lt;em&gt;myapp.xaml.cs&lt;/em&gt; in Part 2.&lt;/p&gt;&lt;p&gt;Now, it's my understanding that XAML is about describing the structure of the code and the design of the objects you want generated whereas C# should be used for the logic (this makes me think of the evolution of Web Programming where HTML sets up the structure of the page, CSS designs it, and some program is on the server-side such as PHP to handle the logic). I'm not going to go through the whole XAML file because I think from understanding parts of it, we can understand all of it.&lt;/p&gt;&lt;p&gt;C# uses curly brackets '{}' for sectioning off blocks of code and they, of course, can be nested. XML uses opening and closing tags. In &lt;em&gt;traditionalclock.xaml&lt;/em&gt;, notice &lt;code&gt;&lt;/code&gt; at the beginning and &lt;code&gt;&lt;/code&gt; at the end and (most) tags can be nested. It's also important to remember the inheritance between objects because when I tried to understand XAML as basically a descriptive markup language to autogenerate C# I got lost in some of the assignments I saw.&lt;/p&gt;&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.window.aspx"&gt;Window Class&lt;/a&gt; has members for "AllowsTransparency", "Background", and "WindowStyle" but "MouseLeftButtonDown" is not on that page in the framework--you have to follow the inheritance: the Window Class inherits from &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.aspx"&gt;ContentControl&lt;/a&gt; which has the MouseLeftButtonDown event because it (eventually) inherits from &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.aspx"&gt;UIElement&lt;/a&gt;. I now understand the importance of paying close attention to the Inheritance Hierarchy for every class overview in the .NET Framework Class Library.&lt;/p&gt;&lt;p&gt;It seems XAML is relatively straight-forward with every opening tag loading a class object, members of that class being assigned in the tag and other, logically connected, classes being set up within the opening and closing tags. Personally, I think coding everything in C# would be just as easy but I guess XAML is nicer from a maintenance and readability perspective as objects are logically grouped within nested tags.&lt;/p&gt;&lt;p&gt;In &lt;em&gt;traditionalclock.xaml.cs&lt;/em&gt; it's easy to see how you can interact with XAML. The first thing I noticed in this file after looking at the XAML for the TraditionalClock class was the line &lt;code&gt;Storyboard clockHandStoryboard = (Storyboard)clockWindow.Resources["clockHandStoryboard"];&lt;/code&gt;. "Storyboard" was set up in XAML as well as the name "clockWindow" and the resource "clockHandStoryboard". The event handlers make sense here too. The only thing I didn't understand was &lt;code&gt;InitializeComponent();&lt;/code&gt;. It's a well named method because I can immediately deduce that it will initialize a component. But What component. As with most questions, &lt;a href="http://stackoverflow.com/questions/245825/what-does-initializecomponent-do-and-how-does-it-work-wpf"&gt;someone has already asked it&lt;/a&gt; on the internet and someone has already given the answer.&lt;/p&gt;&lt;p&gt;Basically, these two files work together as expected. The partial class is created in C# which loads the XAML which gets parsed into objects which can be used in further C# code.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-1647378450570603199?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/1647378450570603199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/1647378450570603199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/1647378450570603199'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-3.html' title='Alarm Clock Sample -- Part 3'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-7271260998720860503</id><published>2009-11-28T22:58:00.000-08:00</published><updated>2010-02-23T03:29:45.475-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='image'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='class'/><category scheme='http://www.blogger.com/atom/ns#' term='namespace'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='property'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='method'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='opacity'/><title type='text'>Alarm Clock Sample -- Part 2</title><content type='html'>&lt;p&gt;Now that I know that &lt;em&gt;myapp.xaml&lt;/em&gt; holds the key to the application's startup, I want to look closer at where the AppStartup method lives: &lt;em&gt;myapp.xaml.cs&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;This file is a complete C# file leveraging the .NET Framework Class Library. The first thing I notice is the file uses six namespaces all ultimately from the System namespace. System is clearly one of the most important namespaces of any C# project. From the descriptions over at the .NET Framework Reference, my first take on their usage is&lt;/p&gt;&lt;ul&gt;&lt;li&gt;System is required for the most fundamental aspects of the application like class and struct types (eg. the Object class from which all other classes are derived&lt;/li&gt;
&lt;li&gt;System.Windows is required because this will be a WPF application&lt;/li&gt;
&lt;li&gt;System.Data has no apparent usage at first glance&lt;/li&gt;
&lt;li&gt;System.Xml is required to parse XAML files since they are XML files&lt;/li&gt;
&lt;li&gt;System.Configuration is required to configure the application (i'm guessing configuration is detailed in the XAML files)&lt;/li&gt;
&lt;li&gt;System.Windows.Media is required for drawing stuff (like the alarm clock image) and producing sound (I don't think this alarm clock actually has an alarm though)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You don't actually have to give everything a namespace but it seems to be a best practice guideline since Microsoft always does it. Here, the application is given the namespace &lt;code&gt;Microsoft.Samples.WinFX.AlarmClock&lt;/code&gt;. So far, I don't think they are necessary unless you plan to write your own library (compiling as DLLs).&lt;/p&gt;&lt;p&gt;On to the meat: &lt;code&gt;public partial class MyApp : Application&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Of course, the application class should be "public" but what's with "partial"? In &lt;a href="http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-1.html"&gt;Part 1&lt;/a&gt;, I mentioned that the build process will automagically create an entry point method so the application knows how to start, I'm guessing the build process also creates a class based on &lt;em&gt;myapp.xaml&lt;/em&gt; which gets put into separate file from the compiled &lt;em&gt;myapp.xaml.cs&lt;/em&gt; in which case "partial" is needed to specify this is just part of the class definition. I gathered as much from &lt;a href="http://msdn.microsoft.com/en-us/library/aa970678.aspx"&gt;Building a WPF Application&lt;/a&gt;&lt;/p&gt;&lt;blockquote&gt;In addition, a language-specific code file is generated for every XAML file. For example, for a Page1.xaml page in a Visual Basic project, a Page1.g.vb is generated; for a Page1.xaml page in a C# project, a Page1.g.cs is generated. The ".g" in the file name indicates the file is generated code that has a partial class declaration for the top-level element of the markup file (such as Page or Window). The class is declared with the partial modifier in C# (Extends in Visual Basic) to indicate there is another declaration for the class elsewhere, usually in the code-behind file Page1.xaml.cs.&lt;/blockquote&gt;&lt;p&gt;The main application class is given the name "MyApp" and inherits from Application which comes from the System.Windows namespace. The &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.application.aspx"&gt;Application class&lt;/a&gt; "Encapsulates a Windows Presentation Foundation (WPF) application." That makes sense, Alarm Clock Sample is a WPF application.&lt;/p&gt;&lt;p&gt;Finally, the application process is run and, on startup, the AppStartup method is called. I already talked about the prototype so let's look at the body:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;TraditionalClock tradClock = new TraditionalClock();&lt;/code&gt; There's an object TraditionalClock defined somewhere (probably in &lt;em&gt;traditionalclock.xaml&lt;/em&gt; and &lt;em&gt;traditionalclock.xaml.cs&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tradClock.Opacity = .6f;&lt;/code&gt; Clearly, this will set the Opacity of the object (which, by now, I'm assuming consists of at least the image of the clock and hands)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tradClock.Show();&lt;/code&gt; Most likely renders the clock to the screen.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The other method, &lt;code&gt;void clockWindow_Closed(object sender, EventArgs e)&lt;/code&gt; is pretty straightforward now that I understand the AppStartup method. It is my understanding that every method triggered by an event will have an "object sender" and "EventArgs e" argument where EventArgs may be different depending on the event. The body of this method merely contains &lt;code&gt;Application.Current.Shutdown(0);&lt;/code&gt; which speaks for itself but the .NET Framework Reference gives some more input: The &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.application.current.aspx"&gt;Current property&lt;/a&gt; is thread safe and allows access to the application's instance in the current &lt;a href="http://msdn.microsoft.com/en-us/library/system.appdomain.aspx"&gt;AppDomain&lt;/a&gt; (kind of like a sandbox for each executing application) from any thread.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-7271260998720860503?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/7271260998720860503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/7271260998720860503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/7271260998720860503'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-2.html' title='Alarm Clock Sample -- Part 2'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-3729557125063520616</id><published>2009-11-28T19:18:00.000-08:00</published><updated>2010-02-23T04:57:33.880-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='image'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='Main()'/><category scheme='http://www.blogger.com/atom/ns#' term='animation'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='dragging'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='opacity'/><category scheme='http://www.blogger.com/atom/ns#' term='compile'/><title type='text'>Alarm Clock Sample -- Part 1</title><content type='html'>&lt;p&gt;The Calculator Demo I visited &lt;a href="http://understanding-c-sharp.blogspot.com/2009/11/calculator-demo-part-1.html"&gt;previously&lt;/a&gt; is far too complex for now so I've decided to try to understand the &lt;a href="http://msdn.microsoft.com/en-us/library/ms756487.aspx"&gt;Alarm Clock Sample&lt;/a&gt; instead. It is a much simpler application though still written for WPF and as such is using XAML.&lt;/p&gt;

&lt;p&gt;Upon downloading the source, I first built the project. This time, there were no problems. The build succeeded and I opened the app. Just as I suspected, it was very simple--just a picture of an old school alarm clock with animated hands, opacity set as to not be opaque, and draggable whilst showing the outline of an outrageously large rectangle. I was surprised, however, that it was taking 50% of my processing power which, on a dual core processor, means it's maxing out probably because of some infinite loop.&lt;/p&gt;

&lt;p&gt;Ok, so now that I see what the program is all about, it's time to dive into the code. I went straight for &lt;em&gt;myapp.xaml&lt;/em&gt; to find &lt;code&gt;Startup&lt;/code&gt;. Thanks to the &lt;a href="http://msdn.microsoft.com/en-us/library/ms743714.aspx"&gt;WPF Application Management Overview&lt;/a&gt;, I know now that this is used to define the handler for the Application.Startup Event which "&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.application.startup.aspx"&gt;Occurs when the Run method of the Application object is called.&lt;/a&gt;"&lt;/p&gt;

&lt;p&gt;I now understand the syntax of &lt;code&gt;void AppStartup(object sender, StartupEventArgs e)&lt;/code&gt; in &lt;em&gt;app.xaml.cs&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;strong&gt;void&lt;/strong&gt; means this method will not return anything (basic knowledge from any strongly typed programming language)&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;AppStartup&lt;/strong&gt; defines the name of the method which will be called on activation of the Application.Startup Event.&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;object sender&lt;/strong&gt; is a reference to the object which raised the event&lt;/li&gt;
 &lt;li&gt;&lt;strong&gt;StartupEventArgs e&lt;/strong&gt; gives access to the properties of the event in question&lt;/li&gt;
&lt;/ul&gt;
 
&lt;p&gt;Cool, but the Startup event "Occurs when the Run method of the Application object is called." Doesn't that mean the application needs a "Run method"? Usually the Run method gets put into the Main method but it doesn't exist in the Alarm Clock Sample just as it didn't exist in the Calculator Demo. No such luck finding Run either. The answer lies in the background. What we don't see in the application nor during the build process is that the entry point Main and the all-important Run get inserted automagically. I felt lucky searching for "wpf main()" and I was. Someone asked &lt;a href="http://learnwpf.com/Posts/Post.aspx?postId=a5643949-ab80-47f9-93c8-f5e8e5782d34"&gt;How can I provide my own Main() method in my WPF application?&lt;/a&gt; (I'll have to look further into that website sometime) and the answer was&lt;/p&gt;

&lt;blockquote&gt;At compile-time WPF generates the real entry point method using the classic static void Main() method signature in C#, or Public Shared Sub Main() in VB.NET. Inside the Main() method WPF creates an instance of one of your classes which derive from System.Windows.Application, and calls the blocking Run() method on this Application-derived class which keeps the process "alive".&lt;/blockquote&gt;
 
&lt;p&gt;Perfect. Now, I can figure out how the app is actually put together rather than how it can exist in the first place.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-3729557125063520616?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/3729557125063520616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/3729557125063520616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/3729557125063520616'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/11/alarm-clock-sample-part-1.html' title='Alarm Clock Sample -- Part 1'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-738013647486262171</id><published>2009-11-28T05:52:00.000-08:00</published><updated>2010-02-23T04:54:58.418-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='Main()'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='compile'/><title type='text'>Calculator Demo -- Part 1</title><content type='html'>&lt;p&gt;After reading through a bunch of the .Net Framework Class Library, I noticed they have some samples for download. I really wanted to dive into GUI programming so I checked out the &lt;a href="http://msdn.microsoft.com/en-us/library/ms771362.aspx"&gt;Calculator Demo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I knew it would be fairly complicated from the description but when I opened the source, I was taken aback by the complexity. As the comments pointed out, it wouldn't compile correctly in the command line because of "missing files" but I still couldn't get that to work so I fired up the behemoth Visual Studio and, it's true, "this example doesn't build unless...".&lt;/p&gt;

&lt;p&gt;The calculator was running, I played around to experience the features, then went back to the source code. From the tutorials I had looked at &lt;a href="http://understanding-c-sharp.blogspot.com/2009/11/initial-resources.html"&gt;previously&lt;/a&gt;, I knew every C# program needed to have a static Main() method as a starting point. I searched every file for "Main" but to no avail. I searched the internet for C# applications without Main() but to no avail.&lt;/p&gt;

&lt;p&gt;Since the easy path to understanding wasn't working out, I stretched my arms and began looking through each source file for the starting point of the application. Eventually, I found &lt;code&gt;Startup="AppStartingUp"&lt;/code&gt; in &lt;em&gt;app.xaml&lt;/em&gt; which quickly led me to &lt;code&gt;void AppStartingUp(object sender, StartupEventArgs e)&lt;/code&gt; in &lt;em&gt;app.xaml.cs&lt;/em&gt; (conveniently enough).&lt;/p&gt;

&lt;p&gt;This discovery didn't help me understand what was happening but it did lead me to search for &lt;a href="http://msdn.microsoft.com/en-us/library/ms747122.aspx"&gt;xaml&lt;/a&gt; which happens to stand for "Extensible Application Markup Language" and, like C# and .NET, was created by Microsoft and looks to be just as complicated.&lt;/p&gt;

&lt;p&gt;Of course, since I had never heard of it before, I realized I would need to find a primer on XAML. &lt;a href="http://www.c-sharpcorner.com/Blogs/BlogDetail.aspx?BlogId=143"&gt;My First XAML Application&lt;/a&gt; is a perfect introduction. As it turns out, the C# language isn't too difficult but .NET is a tremendously large framework which is going to force me to learn a lot more than just C#. I mean, XAML is just part of the &lt;a href="http://msdn.microsoft.com/en-us/library/ms754130.aspx"&gt;Windows Presentation Foundation&lt;/a&gt;!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-738013647486262171?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/738013647486262171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/11/calculator-demo-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/738013647486262171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/738013647486262171'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/11/calculator-demo-part-1.html' title='Calculator Demo -- Part 1'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6007919582257860756.post-5087204632037662918</id><published>2009-11-28T05:10:00.000-08:00</published><updated>2010-02-23T04:59:12.471-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='New Resources'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='introductions'/><category scheme='http://www.blogger.com/atom/ns#' term='c/c++'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Initial Resources</title><content type='html'>&lt;p&gt;There are two reasons I decided to begin learning C#:&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;I'm going to be learning Java next semester for my Masters of IT course but I don't like Java;  C# is based heavily on Java but also influenced by C++; I don't know much about C++ but I really like C&lt;/li&gt;
 &lt;li&gt;I'm looking to have a career in IT; C# is very popular right now; My resume will look better&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here are the places I looked first to get a handle on the language (before starting this blog):&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;a href="http://devhood.com/"&gt;DevHood&lt;/a&gt; -- &lt;a href="http://devhood.com/training_modules/"&gt;Training Modules&lt;/a&gt; -- Distribution A&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://csharp.net-informations.com/"&gt;CSHARP.NET-INFORMATIONS.COM&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://www.ssw.uni-linz.ac.at/Teaching/Lectures/CSharp/Tutorial/"&gt;Hanspeter Mossenbock's C# Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6007919582257860756-5087204632037662918?l=understanding-c-sharp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://understanding-c-sharp.blogspot.com/feeds/5087204632037662918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/11/initial-resources.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/5087204632037662918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6007919582257860756/posts/default/5087204632037662918'/><link rel='alternate' type='text/html' href='http://understanding-c-sharp.blogspot.com/2009/11/initial-resources.html' title='Initial Resources'/><author><name>Justin Mancinelli:</name><uri>http://www.blogger.com/profile/09240344283251946693</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
