<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Colby Cavin - WPF</title>
    <link>http://www.cavinconsulting.com/Colby/</link>
    <description />
    <language>en-us</language>
    <copyright>Cavin Consulting</copyright>
    <lastBuildDate>Thu, 04 Oct 2007 05:41:12 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.1.8102.813</generator>
    <managingEditor>colby@cavinconsulting.com</managingEditor>
    <webMaster>colby@cavinconsulting.com</webMaster>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=7452ced6-002b-4e9c-9ccd-387d225051eb</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,7452ced6-002b-4e9c-9ccd-387d225051eb.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,7452ced6-002b-4e9c-9ccd-387d225051eb.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=7452ced6-002b-4e9c-9ccd-387d225051eb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The Scribble application is back in Visual Studio 2008! Ok, it's not WPF, but at least
it exists (<a title="http://msdn2.microsoft.com/en-us/library/06s5xsah(VS.80).aspx" href="http://msdn2.microsoft.com/en-us/library/06s5xsah(VS.80).aspx">http://msdn2.microsoft.com/en-us/library/06s5xsah(VS.80).aspx</a>).
It even has a tutorial on extending the application to include a plug-in model (<a title="http://msdn2.microsoft.com/en-us/library/11z7687s(VS.80).aspx" href="http://msdn2.microsoft.com/en-us/library/11z7687s(VS.80).aspx">http://msdn2.microsoft.com/en-us/library/11z7687s(VS.80).aspx</a>). 
</p>
        <p>
It probably pays to start with the WinForms version of the example. Make sure you
change the target CPU to Win32 (unless you're on an Itanium) so you'll be able to
compile and debug. From there, you can wander through the code and figure out why
all of the UI is created via code rather than the clever UI form designer that has
been so nicely integrated into VS Orcas (2008). If you figure it out, let me know.
Reading UI and UI layout code isn't my idea of a good time.
</p>
        <p>
After the WinForms example, take a look at the MFC sample. It's a little involved,
but definitely a nice example of integrating native C++/MFC with managed libraries
using managed C++ proxy classes to expose managed interfaces to the plug-in libraries.
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=7452ced6-002b-4e9c-9ccd-387d225051eb" />
      </body>
      <title>WPF Scribble 12</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,7452ced6-002b-4e9c-9ccd-387d225051eb.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/10/04/WPFScribble12.aspx</link>
      <pubDate>Thu, 04 Oct 2007 05:41:12 GMT</pubDate>
      <description>&lt;p&gt;
The Scribble application is back in Visual Studio 2008! Ok, it's not WPF, but at least
it exists (&lt;a title="http://msdn2.microsoft.com/en-us/library/06s5xsah(VS.80).aspx" href="http://msdn2.microsoft.com/en-us/library/06s5xsah(VS.80).aspx"&gt;http://msdn2.microsoft.com/en-us/library/06s5xsah(VS.80).aspx&lt;/a&gt;).
It even has a tutorial on extending the application to include a plug-in model (&lt;a title="http://msdn2.microsoft.com/en-us/library/11z7687s(VS.80).aspx" href="http://msdn2.microsoft.com/en-us/library/11z7687s(VS.80).aspx"&gt;http://msdn2.microsoft.com/en-us/library/11z7687s(VS.80).aspx&lt;/a&gt;). 
&lt;/p&gt;
&lt;p&gt;
It probably pays to start with the WinForms version of the example. Make sure you
change the target CPU to Win32 (unless you're on an Itanium) so you'll be able to
compile and debug. From there, you can wander through the code and figure out why
all of the UI is created via code rather than the clever UI form designer that has
been so nicely integrated into VS Orcas (2008). If you figure it out, let me know.
Reading UI and UI layout code isn't my idea of a good time.
&lt;/p&gt;
&lt;p&gt;
After the WinForms example, take a look at the MFC sample. It's a little involved,
but definitely a nice example of integrating native C++/MFC with managed libraries
using managed C++ proxy classes to expose managed interfaces to the plug-in libraries.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=7452ced6-002b-4e9c-9ccd-387d225051eb" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,7452ced6-002b-4e9c-9ccd-387d225051eb.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=02a4ef38-d594-42b0-beba-f32e8c8ee8a0</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,02a4ef38-d594-42b0-beba-f32e8c8ee8a0.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,02a4ef38-d594-42b0-beba-f32e8c8ee8a0.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=02a4ef38-d594-42b0-beba-f32e8c8ee8a0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This segment looks at localization of button toolips and the descriptive text that
appears in the statusbar when a menu item or button is active. The code for this segment
is available at <a href="http://www.cavinconsulting.com/Code/Scribble11.zip">http://www.cavinconsulting.com/Code/Scribble11.zip</a>.
</p>
        <p>
The general idea is that we want to give helpful hints to our user when if comes to
deciphering the little icons on the screen. Normally, we attach tooltips to tell the
user what each icon does. However, some application go the extra step to make it clear
what a command does by placing a brief description of the actions in the status bar.
This description appears when the menu item or toolbar button becomes "active" and
goes away when the button becomes inactive.
</p>
        <p>
For our purposes, Active will mean the mouse is over a button and or that a menu item
is the focus item on in the application (the latter lets us display description information
even if the menu becomes active via Alt+f,arrow keys).
</p>
        <p>
To implement the GotFocus and LostFocus event handlers for the MenuItems, I went down
a number of paths including style triggers, control templates, and adding event handlers
to each MenuItem individually. The implementation I landed on was to apply an EventSetter
to the MenuItem style like this:
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Window.Resources</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Style</span>
            <span style="color: #ff0000">TargetType</span>=<span style="color: #0000ff">"{x:Type
MenuItem}"</span><span style="color: #ff0000">x</span>:<span style="color: #ff0000">Key</span>=<span style="color: #0000ff">"{x:Type
MenuItem}"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">EventSetter</span><span style="color: #ff0000">Event</span>=<span style="color: #0000ff">"GotFocus"</span><span style="color: #ff0000">Handler</span>=<span style="color: #0000ff">"OnGotFocus"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">EventSetter</span><span style="color: #ff0000">Event</span>=<span style="color: #0000ff">"LostFocus"</span><span style="color: #ff0000">Handler</span>=<span style="color: #0000ff">"OnLostFocus"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Style</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window.Resources</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
From there, we change the declaration of each MenuItem to look like this:
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">MenuItem</span>
            <span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.FileMenuText}"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.New}"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.Open}"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.Save}"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.SaveAs}"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Separator</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.Exit}"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">MenuItem</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
Now, all we have to do is implement the event handlers:
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">void</span> OnGotFocus(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { DisplayCommandDescription(sender); } <span style="color: #0000ff">public</span><span style="color: #0000ff">void</span> OnLostFocus(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { ClearCommandDescription(sender); } </pre>
        </blockquote>
        <p>
Now, the implementation of the Display and Clear functions can look something like
this:
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">void</span> DisplayCommandDescription(<span style="color: #0000ff">object</span> sender)
{ MenuItem item = sender <span style="color: #0000ff">as</span> MenuItem; <span style="color: #0000ff">if</span> ((<span style="color: #0000ff">null</span> !=
item) &amp;&amp; (<span style="color: #0000ff">null</span> != item.Command)) { ScribbleCommand
command = item.Command <span style="color: #0000ff">as</span> ScribbleCommand; <span style="color: #0000ff">if</span> (<span style="color: #0000ff">null</span> !=
command) { StatusText = command.Description; } } ScribbleButton button = sender <span style="color: #0000ff">as</span> ScribbleButton; <span style="color: #0000ff">if</span> (<span style="color: #0000ff">null</span> !=
button) { StatusText = button.Description; } } <span style="color: #0000ff">private</span><span style="color: #0000ff">void</span> ClearCommandDescription(<span style="color: #0000ff">object</span> sender)
{ StatusText = ScribbleCommands.StatusbarText; }</pre>
        </blockquote>
        <p>
Of course, if you compile and run at this point, you'll get an error about StatusText
not existing. That's because it doesn't. Of course, you could just change that to
_statusBar.Content, but that would be directly manipulating the UI from code. According
to the rumor, it's better to set a property somewhere that notifies the observers
that it has changed. So, that's what we'll do, by adding a dependency property to
our main window:
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">static</span> MainWindow() { StatusTextProperty
= DependencyProperty.Register( "<span style="color: #8b0000">StatusText</span>", <span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">string</span>), <span style="color: #0000ff">typeof</span>(MainWindow), <span style="color: #0000ff">new</span> FrameworkPropertyMetadata(String.Empty,
FrameworkPropertyMetadataOptions.AffectsRender)); } <span style="color: #0000ff">public</span><span style="color: #0000ff">static</span> DependencyProperty
StatusTextProperty; <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> StatusText
{ <span style="color: #0000ff">get</span> { <span style="color: #0000ff">return</span> (<span style="color: #0000ff">string</span>)GetValue(StatusTextProperty);
} <span style="color: #0000ff">set</span> { SetValue(StatusTextProperty, <span style="color: #0000ff">value</span>);
} }</pre>
        </blockquote>
        <p>
Now, we can databind the status bar's content to the main window's StatusText dependency
property (we've added x:Name="main" to the Window tag at the top):
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">StatusBar</span>
            <span style="color: #ff0000">DockPanel</span>.<span style="color: #ff0000">Dock</span>=<span style="color: #0000ff">"Bottom"</span><span style="color: #ff0000">Visibility</span>=<span style="color: #0000ff">"{Binding
Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=_viewStatusBar}"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Label</span><span style="color: #ff0000">x</span>:<span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"_statusBarText"</span><span style="color: #ff0000">Content</span>=<span style="color: #0000ff">"{Binding
ElementName=main, Path=StatusText}"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">StatusBar</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
Now, a little bit about the ScribbleCommand class. The ScribbleCommands class was
getting a little tedious, so I wrote the ScribbleCommand class to encapsulate all
of the information we need in order to attach to a menu item or a button. It inherits
from RoutedUICommand so it plays nicely with the expectations of WPF. Really, it's
just a RoutedUICommand with additional properties for Description and Tooltip. 
</p>
        <p>
For the status bar text on the buttons, I tried a different approach. Rather than
checking for a command of a particular type in the activate and deactivate handlers,
I checked if it was one of my own buttons that had a Description property. This helped
in a few ways, one of which was that my inherited class was able to override the Tooltip
property with that of the attached command. I'm not sure if this is a good approach
or a blatant violation of some of the separation principles we were hoping to instill
with the command pattern. I'll lay it out, anyway, and we'll see what we can make
of it later.
</p>
        <p>
The ScribbleButton inherits from Button, and has a text dependency property called
Description (just like StatusText above). Also, it listens to the OnPropertyChanged
event to see when the Command property is changed. If we get attached to a ScribbleCommand,
then we set our tooltip and description according to the ScribbleCommand.
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">static</span> ScribbleButton() { DescriptionProperty
= DependencyProperty.Register( "<span style="color: #8b0000">Description</span>", <span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">string</span>), <span style="color: #0000ff">typeof</span>(ScribbleButton), <span style="color: #0000ff">new</span> FrameworkPropertyMetadata(String.Empty,
FrameworkPropertyMetadataOptions.AffectsRender)); } <span style="color: #0000ff">public</span><span style="color: #0000ff">static</span> DependencyProperty
DescriptionProperty; <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Description
{ <span style="color: #0000ff">get</span> { <span style="color: #0000ff">return</span> (<span style="color: #0000ff">string</span>)GetValue(DescriptionProperty);
} <span style="color: #0000ff">set</span> { SetValue(DescriptionProperty, <span style="color: #0000ff">value</span>);
} } <span style="color: #0000ff">protected</span><span style="color: #0000ff">override</span><span style="color: #0000ff">void</span> OnPropertyChanged(DependencyPropertyChangedEventArgs
e) { <span style="color: #0000ff">base</span>.OnPropertyChanged(e); <span style="color: #0000ff">if</span>(0==<span style="color: #0000ff">string</span>.Compare(e.Property.Name,"<span style="color: #8b0000">Command</span>"))
{ ScribbleCommand newCommand = e.NewValue <span style="color: #0000ff">as</span> ScribbleCommand; <span style="color: #0000ff">if</span> (<span style="color: #0000ff">null</span>!=newCommand)
{ ToolTip = newCommand.Tooltip; Description = newCommand.Description; } } }</pre>
        </blockquote>
        <p>
We do something similar to the GotFocus, LostFocus trick to hook up mouse focus:
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Style</span>
            <span style="color: #ff0000">TargetType</span>=<span style="color: #0000ff">"{x:Type
scribble:ScribbleButton}"</span><span style="color: #ff0000">x</span>:<span style="color: #ff0000">Key</span>=<span style="color: #0000ff">"{x:Type
scribble:ScribbleButton}"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">EventSetter</span><span style="color: #ff0000">Event</span>=<span style="color: #0000ff">"MouseEnter"</span><span style="color: #ff0000">Handler</span>=<span style="color: #0000ff">"OnMouseEnter"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">EventSetter</span><span style="color: #ff0000">Event</span>=<span style="color: #0000ff">"MouseLeave"</span><span style="color: #ff0000">Handler</span>=<span style="color: #0000ff">"OnMouseLeave"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Style</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
And that's it. We finally have an application that looks like an application, localizes
nicely, and takes advantage of some of the new features of WPF. I think this is probably
the end of the Scribble tutorial, as such. I'm still not entirely convinced I've learned
the localization model MS is trying to get across. Every example I see uses that LocBaml
example and editing values in Excel. I'm not entirely convinced that's the correct
route either.
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=02a4ef38-d594-42b0-beba-f32e8c8ee8a0" />
      </body>
      <title>WPF Scribble 11</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,02a4ef38-d594-42b0-beba-f32e8c8ee8a0.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/08/03/WPFScribble11.aspx</link>
      <pubDate>Fri, 03 Aug 2007 05:40:13 GMT</pubDate>
      <description>&lt;p&gt;
This segment looks at localization of button toolips and the descriptive text that
appears in the statusbar when a menu item or button is active. The code for this segment
is available at &lt;a href="http://www.cavinconsulting.com/Code/Scribble11.zip"&gt;http://www.cavinconsulting.com/Code/Scribble11.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The general idea is that we want to give helpful hints to our user when if comes to
deciphering the little icons on the screen. Normally, we attach tooltips to tell the
user what each icon does. However, some application go the extra step to make it clear
what a command does by placing a brief description of the actions in the status bar.
This description appears when the menu item or toolbar button becomes "active" and
goes away when the button becomes inactive.
&lt;/p&gt;
&lt;p&gt;
For our purposes, Active will mean the mouse is over a button and or that a menu item
is the focus item on in the application (the latter lets us display description information
even if the menu becomes active via Alt+f,arrow keys).
&lt;/p&gt;
&lt;p&gt;
To implement the GotFocus and LostFocus event handlers for the MenuItems, I went down
a number of paths including style triggers, control templates, and adding event handlers
to each MenuItem individually. The implementation I landed on was to apply an EventSetter
to the MenuItem style like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Window.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Style&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TargetType&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Type
MenuItem}"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Key&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Type
MenuItem}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;EventSetter&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Event&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"GotFocus"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Handler&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnGotFocus"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;EventSetter&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Event&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LostFocus"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Handler&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnLostFocus"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Window.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
From there, we change the declaration of each MenuItem to look like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.FileMenuText}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.New}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.Open}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.Save}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.SaveAs}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Separator&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.Exit}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Now, all we have to do is implement the event handlers:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnGotFocus(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { DisplayCommandDescription(sender); } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnLostFocus(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { ClearCommandDescription(sender); } &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Now, the implementation of the Display and Clear functions can look something like
this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DisplayCommandDescription(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender)
{ MenuItem item = sender &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; MenuItem; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((&lt;span style="color: #0000ff"&gt;null&lt;/span&gt; !=
item) &amp;amp;&amp;amp; (&lt;span style="color: #0000ff"&gt;null&lt;/span&gt; != item.Command)) { ScribbleCommand
command = item.Command &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; ScribbleCommand; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;null&lt;/span&gt; !=
command) { StatusText = command.Description; } } ScribbleButton button = sender &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; ScribbleButton; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;null&lt;/span&gt; !=
button) { StatusText = button.Description; } } &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ClearCommandDescription(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender)
{ StatusText = ScribbleCommands.StatusbarText; }&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Of course, if you compile and run at this point, you'll get an error about StatusText
not existing. That's because it doesn't. Of course, you could just change that to
_statusBar.Content, but that would be directly manipulating the UI from code. According
to the rumor, it's better to set a property somewhere that notifies the observers
that it has changed. So, that's what we'll do, by adding a dependency property to
our main window:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; MainWindow() { StatusTextProperty
= DependencyProperty.Register( "&lt;span style="color: #8b0000"&gt;StatusText&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;), &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(MainWindow), &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FrameworkPropertyMetadata(String.Empty,
FrameworkPropertyMetadataOptions.AffectsRender)); } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; DependencyProperty
StatusTextProperty; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; StatusText
{ &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;)GetValue(StatusTextProperty);
} &lt;span style="color: #0000ff"&gt;set&lt;/span&gt; { SetValue(StatusTextProperty, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);
} }&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Now, we can databind the status bar's content to the main window's StatusText dependency
property (we've added x:Name="main" to the Window tag at the top):
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StatusBar&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DockPanel&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Dock&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Bottom"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Visibility&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding
Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=_viewStatusBar}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Label&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_statusBarText"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding
ElementName=main, Path=StatusText}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;StatusBar&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Now, a little bit about the ScribbleCommand class. The ScribbleCommands class was
getting a little tedious, so I wrote the ScribbleCommand class to encapsulate all
of the information we need in order to attach to a menu item or a button. It inherits
from RoutedUICommand so it plays nicely with the expectations of WPF. Really, it's
just a RoutedUICommand with additional properties for Description and Tooltip. 
&lt;/p&gt;
&lt;p&gt;
For the status bar text on the buttons, I tried a different approach. Rather than
checking for a command of a particular type in the activate and deactivate handlers,
I checked if it was one of my own buttons that had a Description property. This helped
in a few ways, one of which was that my inherited class was able to override the Tooltip
property with that of the attached command. I'm not sure if this is a good approach
or a blatant violation of some of the separation principles we were hoping to instill
with the command pattern. I'll lay it out, anyway, and we'll see what we can make
of it later.
&lt;/p&gt;
&lt;p&gt;
The ScribbleButton inherits from Button, and has a text dependency property called
Description (just like StatusText above). Also, it listens to the OnPropertyChanged
event to see when the Command property is changed. If we get attached to a ScribbleCommand,
then we set our tooltip and description according to the ScribbleCommand.
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; ScribbleButton() { DescriptionProperty
= DependencyProperty.Register( "&lt;span style="color: #8b0000"&gt;Description&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;), &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(ScribbleButton), &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FrameworkPropertyMetadata(String.Empty,
FrameworkPropertyMetadataOptions.AffectsRender)); } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; DependencyProperty
DescriptionProperty; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Description
{ &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;)GetValue(DescriptionProperty);
} &lt;span style="color: #0000ff"&gt;set&lt;/span&gt; { SetValue(DescriptionProperty, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);
} } &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnPropertyChanged(DependencyPropertyChangedEventArgs
e) { &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.OnPropertyChanged(e); &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(0==&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Compare(e.Property.Name,"&lt;span style="color: #8b0000"&gt;Command&lt;/span&gt;"))
{ ScribbleCommand newCommand = e.NewValue &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; ScribbleCommand; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;!=newCommand)
{ ToolTip = newCommand.Tooltip; Description = newCommand.Description; } } }&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
We do something similar to the GotFocus, LostFocus trick to hook up mouse focus:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Style&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TargetType&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Type
scribble:ScribbleButton}"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Key&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Type
scribble:ScribbleButton}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;EventSetter&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Event&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"MouseEnter"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Handler&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnMouseEnter"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;EventSetter&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Event&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"MouseLeave"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Handler&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnMouseLeave"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
And that's it. We finally have an application that looks like an application, localizes
nicely, and takes advantage of some of the new features of WPF. I think this is probably
the end of the Scribble tutorial, as such. I'm still not entirely convinced I've learned
the localization model MS is trying to get across. Every example I see uses that LocBaml
example and editing values in Excel. I'm not entirely convinced that's the correct
route either.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=02a4ef38-d594-42b0-beba-f32e8c8ee8a0" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,02a4ef38-d594-42b0-beba-f32e8c8ee8a0.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=2211eb07-f6dd-4543-b657-574ef4f1c79b</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,2211eb07-f6dd-4543-b657-574ef4f1c79b.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,2211eb07-f6dd-4543-b657-574ef4f1c79b.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=2211eb07-f6dd-4543-b657-574ef4f1c79b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Here we are on the 10th installment of what I thought would be a pretty simple walk-through
into writing standard, distributable applications using WPF. This walk-through started
out mirroring the old Scribble tutorial (<a title="http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx" href="http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx">http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx</a>)
but has recently turned into me complaining about things I don't understand very well.
Specifically, I'm just not getting my head around the localization story with WPF
and how it interacts with the built-in ApplicationCommands.X classes and keyboard
access (mnemonics in  MFC). So, rather than complaining, let's just solve the
problem.
</p>
        <p>
The problem is this: ApplicationCommands.X classes give the developer a nice, automatically
localized hook to use in hooking up UI elements to business logic to be executed.
These commands are automatically localized based on the currently selected UI culture.
These commands don't have access keys for use in MenuItem UI elements, so if I use
the ApplicationCommands.New command in the file menu, I can't invoke it via Alt+f,s
(something I've been doing from the old DOS days and am not interested in changing).
</p>
        <p>
Solution 1 -- Implementing our own ScribbleCommands class from scratch
</p>
        <p>
Here's a possible example. We could just implement our own ApplicationCommands-like
class to serve up all of the commands we're interested in using from the UI. After
all, we already implemented ScribbleCommands.Exit, so we can do something like that
for the rest of the commands. This has the downside of requiring us to localize all
of the text ourselves.
</p>
        <p>
Solution 2 -- Implementing our own ScribbleCommands class as an adapter around ApplicationCommands
</p>
        <p>
This is the one we're going to pursue. Since we already have ScribbleCommands and
since MS already gives us much of the plumbing for the built-in commands classes,
we'll just enhance that built-in functionality to convince it to do what we want.
Here's the idea: for commands that don't have built-in ApplicationCommands.X implementation,
we create string resources for all UI related aspects of the command (Name, Text,
Gextures, Gesture display text, Tooltip, and Description). For commands that do have
a built-in ApplicationCommands.X implementation, we create string resources for the
bits of UI related aspects we want to override (mnemonic character, Tooltip, and Description).
</p>
        <p>
The Scribble.Exit command looks like this:
</p>
        <blockquote>
          <pre>
            <span style="COLOR: #0000ff">public</span>
            <span style="COLOR: #0000ff">static</span> RoutedUICommand
Exit { <span style="COLOR: #0000ff">get</span> { <span style="COLOR: #0000ff">return</span> EnsureCommand(
Properties.Resources.ExitName, Properties.Resources.ExitText, Properties.Resources.ExitGestures,
Properties.Resources.ExitGesturesDisplayText); } } <span style="COLOR: #0000ff">public</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #0000ff">string</span> ExitTooltip
{ <span style="COLOR: #0000ff">get</span> { <span style="COLOR: #0000ff">return</span> Properties.Resources.ExitTooltip;
} } <span style="COLOR: #0000ff">public</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #0000ff">string</span> ExitDescription
{ <span style="COLOR: #0000ff">get</span> { <span style="COLOR: #0000ff">return</span> Properties.Resources.ExitDescription;
} }</pre>
        </blockquote>
        <p>
The Scribble.New command looks like this:
</p>
        <blockquote>
          <pre>
            <span style="COLOR: #0000ff">public</span>
            <span style="COLOR: #0000ff">static</span> RoutedUICommand
New { <span style="COLOR: #0000ff">get</span> { RoutedUICommand command = ApplicationCommands.New; <span style="COLOR: #0000ff">string</span> commandText
= command.Text; <span style="COLOR: #0000ff">int</span> accessIndex = commandText.IndexOf(Properties.Resources.NewAccessKey); <span style="COLOR: #0000ff">if</span> ((accessIndex
&gt;= 0) &amp;&amp; (commandText.IndexOf('_') &lt; 0)) { command.Text = commandText.Insert(accessIndex,
"<span style="COLOR: #8b0000">_</span>"); } <span style="COLOR: #0000ff">return</span> command;
} } <span style="COLOR: #0000ff">public</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #0000ff">string</span> NewTooltip
{ <span style="COLOR: #0000ff">get</span> { <span style="COLOR: #0000ff">return</span> Properties.Resources.NewTooltip;
} } <span style="COLOR: #0000ff">public</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #0000ff">string</span> NewDescription
{ <span style="COLOR: #0000ff">get</span> { <span style="COLOR: #0000ff">return</span> Properties.Resources.NewDescription;
} }</pre>
        </blockquote>
        <p>
Notice, we have to use our own Tooltip and Description properties here since the built-in
commands don't have these items provided. Also, notice we are searching the returned
command.Text for a pre-existing _ character. This is so we don't forcibly overwrite
any mnemonic that may already be set. Of course, you could just remove it instead.
</p>
        <p>
Using any of these commands in the UI looks exactly the same as before
</p>
        <blockquote>
          <pre>
            <span style="COLOR: #0000ff">&lt;</span>
            <span style="COLOR: #800000">MenuItem</span>
            <span style="COLOR: #ff0000">Command</span>=<span style="COLOR: #0000ff">"{x:Static
scribble:ScribbleCommands.New}"</span><span style="COLOR: #0000ff">/&gt;</span></pre>
        </blockquote>
        <p>
There it is. The code (in Spanish and English) is available at <a href="http://www.cavinconsulting.com/Code/Scribble10.zip">http://www.cavinconsulting.com/Code/Scribble10.zip</a>.
To run it in Spanish, just un-comment the marked lines in App.xaml.cs. If you're running
Windows XP, be sure to install the Spanish language pack for the .NET 3.0 Framework
(<a title="http://www.microsoft.com/downloads/details.aspx?FamilyID=41c61d2a-d411-4dde-9013-bb08eb688bb6&amp;DisplayLang=en" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=41c61d2a-d411-4dde-9013-bb08eb688bb6&amp;DisplayLang=en">http://www.microsoft.com/downloads/details.aspx?FamilyID=41c61d2a-d411-4dde-9013-bb08eb688bb6&amp;DisplayLang=en</a>).
Unfortunately, if you're running Vista, it isn't as simple as just installing the
language pack. If you have Ultimate or Enterprise edition, you should see the language
packs on Utimate Updates. I didn't, however, and ended up downloading it directly
from <a href="http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/lp-es-es_a163c4bbc9c34f2e299c057ef8861f0fa3d8a76d.exe">here</a>.
</p>
        <p>
I'm still not sure what I think about this approach. It does salvage the automatic
localization provided by the runtime. It allows each language to define their own
mnemonics or to fall back on the default mnemonic (if the latter exists in the command).
However, on windows Vista, the localization only appears supported on Ultimate or
Enterprise editions, and the installation of the appropriate MUI packs doesn't seem
as simple as the old language pack model. Also, it limits my target audience to only
those fortunate enough to be running an expensive version of Windows.
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=2211eb07-f6dd-4543-b657-574ef4f1c79b" />
      </body>
      <title>WPF Scribble 10</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,2211eb07-f6dd-4543-b657-574ef4f1c79b.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/07/17/WPFScribble10.aspx</link>
      <pubDate>Tue, 17 Jul 2007 05:39:29 GMT</pubDate>
      <description>&lt;p&gt;
Here we are on the 10th installment of what I thought would be a pretty simple walk-through
into writing standard, distributable applications using WPF. This walk-through started
out mirroring the old Scribble tutorial (&lt;a title=http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx href="http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx"&gt;http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx&lt;/a&gt;)
but has recently turned into me complaining about things I don't understand very well.
Specifically, I'm just not getting my head around the localization story with WPF
and how it interacts with the built-in ApplicationCommands.X classes and keyboard
access (mnemonics in&amp;nbsp; MFC). So, rather than complaining, let's just solve the
problem.
&lt;/p&gt;
&lt;p&gt;
The problem is this: ApplicationCommands.X classes give the developer a nice, automatically
localized hook to use in hooking up UI elements to business logic to be executed.
These commands are automatically localized based on the currently selected UI culture.
These commands don't have access keys for use in MenuItem UI elements, so if I use
the ApplicationCommands.New command in the file menu, I can't invoke it via Alt+f,s
(something I've been doing from the old DOS days and am not interested in changing).
&lt;/p&gt;
&lt;p&gt;
Solution 1 -- Implementing our own ScribbleCommands class from scratch
&lt;/p&gt;
&lt;p&gt;
Here's a possible example. We could just implement our own ApplicationCommands-like
class to serve up all of the commands we're interested in using from the UI. After
all, we already implemented ScribbleCommands.Exit, so we can do something like that
for the rest of the commands. This has the downside of requiring us to localize all
of the text ourselves.
&lt;/p&gt;
&lt;p&gt;
Solution 2 -- Implementing our own ScribbleCommands class as an adapter around ApplicationCommands
&lt;/p&gt;
&lt;p&gt;
This is the one we're going to pursue. Since we already have ScribbleCommands and
since MS already gives us much of the plumbing for the built-in commands classes,
we'll just enhance that built-in functionality to convince it to do what we want.
Here's the idea: for commands that don't have built-in ApplicationCommands.X implementation,
we create string resources for all UI related aspects of the command (Name, Text,
Gextures, Gesture display text, Tooltip, and Description). For commands that do have
a built-in ApplicationCommands.X implementation, we create string resources for the
bits of UI related aspects we want to override (mnemonic character, Tooltip, and Description).
&lt;/p&gt;
&lt;p&gt;
The Scribble.Exit command looks like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;static&lt;/span&gt; RoutedUICommand
Exit { &lt;span style="COLOR: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt; EnsureCommand(
Properties.Resources.ExitName, Properties.Resources.ExitText, Properties.Resources.ExitGestures,
Properties.Resources.ExitGesturesDisplayText); } } &lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;static&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; ExitTooltip
{ &lt;span style="COLOR: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt; Properties.Resources.ExitTooltip;
} } &lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;static&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; ExitDescription
{ &lt;span style="COLOR: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt; Properties.Resources.ExitDescription;
} }&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
The Scribble.New command looks like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;static&lt;/span&gt; RoutedUICommand
New { &lt;span style="COLOR: #0000ff"&gt;get&lt;/span&gt; { RoutedUICommand command = ApplicationCommands.New; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; commandText
= command.Text; &lt;span style="COLOR: #0000ff"&gt;int&lt;/span&gt; accessIndex = commandText.IndexOf(Properties.Resources.NewAccessKey); &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt; ((accessIndex
&amp;gt;= 0) &amp;amp;&amp;amp; (commandText.IndexOf('_') &amp;lt; 0)) { command.Text = commandText.Insert(accessIndex,
"&lt;span style="COLOR: #8b0000"&gt;_&lt;/span&gt;"); } &lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt; command;
} } &lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;static&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; NewTooltip
{ &lt;span style="COLOR: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt; Properties.Resources.NewTooltip;
} } &lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;static&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; NewDescription
{ &lt;span style="COLOR: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt; Properties.Resources.NewDescription;
} }&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Notice, we have to use our own Tooltip and Description properties here since the built-in
commands don't have these items provided. Also, notice we are searching the returned
command.Text for a pre-existing _ character. This is so we don't forcibly overwrite
any mnemonic that may already be set. Of course, you could just remove it instead.
&lt;/p&gt;
&lt;p&gt;
Using any of these commands in the UI looks exactly the same as before
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="COLOR: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.New}"&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
There it is. The code (in Spanish and English) is available at &lt;a href="http://www.cavinconsulting.com/Code/Scribble10.zip"&gt;http://www.cavinconsulting.com/Code/Scribble10.zip&lt;/a&gt;.
To run it in Spanish, just un-comment the marked lines in App.xaml.cs. If you're running
Windows XP, be sure to install the Spanish language pack for the .NET 3.0 Framework
(&lt;a title=http://www.microsoft.com/downloads/details.aspx?FamilyID=41c61d2a-d411-4dde-9013-bb08eb688bb6&amp;amp;DisplayLang=en href="http://www.microsoft.com/downloads/details.aspx?FamilyID=41c61d2a-d411-4dde-9013-bb08eb688bb6&amp;amp;DisplayLang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=41c61d2a-d411-4dde-9013-bb08eb688bb6&amp;amp;DisplayLang=en&lt;/a&gt;).
Unfortunately, if you're running Vista, it isn't as simple as just installing the
language pack. If you have Ultimate or Enterprise edition, you should see the language
packs on Utimate Updates. I didn't, however, and ended up downloading it directly
from &lt;a href="http://download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/lp-es-es_a163c4bbc9c34f2e299c057ef8861f0fa3d8a76d.exe"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
I'm still not sure what I think about this approach. It does salvage the automatic
localization provided by the runtime. It allows each language to define their own
mnemonics or to fall back on the default mnemonic (if the latter exists in the command).
However, on windows Vista, the localization only appears supported on Ultimate or
Enterprise editions, and the installation of the appropriate MUI packs doesn't seem
as simple as the old language pack model. Also, it limits my target audience to only
those fortunate enough to be running an expensive version of Windows.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=2211eb07-f6dd-4543-b657-574ef4f1c79b" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,2211eb07-f6dd-4543-b657-574ef4f1c79b.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=af3f483d-1b2c-4290-a003-5362d9255d44</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,af3f483d-1b2c-4290-a003-5362d9255d44.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,af3f483d-1b2c-4290-a003-5362d9255d44.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=af3f483d-1b2c-4290-a003-5362d9255d44</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Up to this point, we've been concentrating on the infrastructure aspect of what it
takes to make a "standard" application using WPF. We aren't quite there yet. The localization
story for WPF applications is pretty fuzzy as is the keyboard accessibility framework.
More importantly, getting the two to work together is questionable, at best.
</p>
        <p>
The story so far:
</p>
        <p>
WPF makes heavy use of the Command pattern for hooking execution logic to different
UI elements. The WPF framework provides us with a number of built-in commands for
our use (like ApplicationCommands.New, and EditingCommands.AlignCenter. Here are my
impressions on using these commands out of the box: 
</p>
        <p>
The Good
</p>
        <ul>
          <li>
UI elements which are "command aware" can have many of their properties localized
to the current UI culture without the programmer having to do anything. 
</li>
          <li>
Having so many canned commands makes it all the more likely that developers will actually
use the command pattern for their own commands. 
</li>
          <li>
Most commands are decorated with commonly KeyGestures so things like Ctrl+C or Shift+Delete
invokes the ApplicationCommands.Copy command without the programmer having to do anything.</li>
        </ul>
        <p>
The Bad
</p>
        <ul>
          <li>
The localized commands do not have a method (that I have found) to designate a mnemonic
(now called an access key) for easy, localizable keyboard access inside a MenuItem.
So, I haven't found a way to attach the ApplicationCommands.Save command to an item
under the _File MenuItem and have the key sequence Alt+f,s invoke the save command.
This is a big problem for me because I routinely use Alt+f,s to save rather than Ctrl+s.
I may be the only one in the world, since it's a throwback to the old DOS editor,
but I still use it. 
</li>
          <li>
There doesn't seem to be a really friendly way to extend or specialize the built-in
commands overriding just the information you want to specialize. Instead, I resort
to duplicating the built-in command, thereby loosing the automatic localization capabilities.</li>
        </ul>
        <p>
The localization story in WPF is also a little confusing to me. What with all of the
different types of resources available (resource dictionaries in App.xaml, and Window.xaml
along with the standard Properties.Resource available in .NET 2.0) it is unclear to
me how a developer is expected to make robust, localizable applications. So far, I
have encountered several discussions on how it can be done, but most of them rely
on a pretty flimsy example application (LocBaml), this article <a title="http://msdn2.microsoft.com/en-us/library/ms753931.aspx" href="http://msdn2.microsoft.com/en-us/library/ms753931.aspx">http://msdn2.microsoft.com/en-us/library/ms753931.aspx</a> and
some clumsy hand-editing of both ApplicationSettings.cs and the .csproj file. Moreover,
the localization mechanism is by way of replacing the localizable strings in a .csv
file. What happened to the localizable resource editor we had in MFC 10 years ago?
Moreover, we already have a mechanism for localizing resources for a .NET 2.0 application.
Ultimately, the Baml information just gets stored as a localizable resource in the
executable. Why is there no tool support here?
</p>
        <p>
To be fair, I'm sure Microsoft hasn't forgotten that agencies other than Microsoft
produce multi-cultural applications. On the contrary, I'd like to think that easy
localization of an application is very important to Microsoft. However, I'm just not
seeing that coming out of their new toolsets. It doesn't look like there will be anything
of the sort in the Orcas timeframe either.
</p>
        <p>
Why all the fuss? I started this project out simply trying to create a "generic" desktop
application using the WPF framework. By generic, I mean just what the original MFC
Scribble tutorial was -- a simple, standard, Windows application with all of the appropriate
Windowsy goodness like tooltips, keyboard access, shortcuts, and localization. When
it comes down to it, writing such an application in WPF appears to be a lot more work
than I think it should be.
</p>
        <p>
I still plan on pursuing this project as I think it is important that developers understand
the importance of a "standard" look and feel even though our new toolsets open up
the possibility to diverge from that standard (or create a new one). Also, I think
it is always important to remember that there are other languages besides English.
By remembering this, and designing for it, we can ensure the ability to localize our
applications for markets we may otherwise be ineligible to join.
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=af3f483d-1b2c-4290-a003-5362d9255d44" />
      </body>
      <title>WPF Scribble 9</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,af3f483d-1b2c-4290-a003-5362d9255d44.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/07/07/WPFScribble9.aspx</link>
      <pubDate>Sat, 07 Jul 2007 05:38:56 GMT</pubDate>
      <description>&lt;p&gt;
Up to this point, we've been concentrating on the infrastructure aspect of what it
takes to make a "standard" application using WPF. We aren't quite there yet. The localization
story for WPF applications is pretty fuzzy as is the keyboard accessibility framework.
More importantly, getting the two to work together is questionable, at best.
&lt;/p&gt;
&lt;p&gt;
The story so far:
&lt;/p&gt;
&lt;p&gt;
WPF makes heavy use of the Command pattern for hooking execution logic to different
UI elements. The WPF framework provides us with a number of built-in commands for
our use (like ApplicationCommands.New, and EditingCommands.AlignCenter. Here are my
impressions on using these commands out of the box: 
&lt;/p&gt;
&lt;p&gt;
The Good
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
UI elements which are "command aware" can have many of their properties localized
to the current UI culture without the programmer having to do anything. 
&lt;li&gt;
Having so many canned commands makes it all the more likely that developers will actually
use the command pattern for their own commands. 
&lt;li&gt;
Most commands are decorated with commonly KeyGestures so things like Ctrl+C or Shift+Delete
invokes the ApplicationCommands.Copy command without the programmer having to do anything.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The Bad
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The localized commands do not have a method (that I have found) to designate a mnemonic
(now called an access key) for easy, localizable keyboard access inside a MenuItem.
So, I haven't found a way to attach the ApplicationCommands.Save command to an item
under the _File MenuItem and have the key sequence Alt+f,s invoke the save command.
This is a big problem for me because I routinely use Alt+f,s to save rather than Ctrl+s.
I may be the only one in the world, since it's a throwback to the old DOS editor,
but I still use it. 
&lt;li&gt;
There doesn't seem to be a really friendly way to extend or specialize the built-in
commands overriding just the information you want to specialize. Instead, I resort
to duplicating the built-in command, thereby loosing the automatic localization capabilities.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The localization story in WPF is also a little confusing to me. What with all of the
different types of resources available (resource dictionaries in App.xaml, and Window.xaml
along with the standard Properties.Resource available in .NET 2.0) it is unclear to
me how a developer is expected to make robust, localizable applications. So far, I
have encountered several discussions on how it can be done, but most of them rely
on a pretty flimsy example application (LocBaml), this article &lt;a title="http://msdn2.microsoft.com/en-us/library/ms753931.aspx" href="http://msdn2.microsoft.com/en-us/library/ms753931.aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms753931.aspx&lt;/a&gt; and
some clumsy hand-editing of both ApplicationSettings.cs and the .csproj file. Moreover,
the localization mechanism is by way of replacing the localizable strings in a .csv
file. What happened to the localizable resource editor we had in MFC 10 years ago?
Moreover, we already have a mechanism for localizing resources for a .NET 2.0 application.
Ultimately, the Baml information just gets stored as a localizable resource in the
executable. Why is there no tool support here?
&lt;/p&gt;
&lt;p&gt;
To be fair, I'm sure Microsoft hasn't forgotten that agencies other than Microsoft
produce multi-cultural applications. On the contrary, I'd like to think that easy
localization of an application is very important to Microsoft. However, I'm just not
seeing that coming out of their new toolsets. It doesn't look like there will be anything
of the sort in the Orcas timeframe either.
&lt;/p&gt;
&lt;p&gt;
Why all the fuss? I started this project out simply trying to create a "generic" desktop
application using the WPF framework. By generic, I mean just what the original MFC
Scribble tutorial was -- a simple, standard, Windows application with all of the appropriate
Windowsy goodness like tooltips, keyboard access, shortcuts, and localization. When
it comes down to it, writing such an application in WPF appears to be a lot more work
than I think it should be.
&lt;/p&gt;
&lt;p&gt;
I still plan on pursuing this project as I think it is important that developers understand
the importance of a "standard" look and feel even though our new toolsets open up
the possibility to diverge from that standard (or create a new one). Also, I think
it is always important to remember that there are other languages besides English.
By remembering this, and designing for it, we can ensure the ability to localize our
applications for markets we may otherwise be ineligible to join.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=af3f483d-1b2c-4290-a003-5362d9255d44" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,af3f483d-1b2c-4290-a003-5362d9255d44.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=564b7c09-d30a-421c-b0e8-c2824a0af0b5</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,564b7c09-d30a-421c-b0e8-c2824a0af0b5.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,564b7c09-d30a-421c-b0e8-c2824a0af0b5.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=564b7c09-d30a-421c-b0e8-c2824a0af0b5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The code for this segment is available at <a href="http://www.cavinconsulting.com/Code/Scribble8.zip">http://www.cavinconsulting.com/Code/Scribble8.zip</a>.
</p>
        <p>
By now, we've gotten through most of the Scribble framework (writing a real Windows-like
application using WPF). Of course, I'm sure there are better ways to do what I'm doing,
but that's fine. Here's a short installment on vector icons instead of .bmp/.png icons.
</p>
        <p>
In our previous steps, we displayed our toolbar buttons with something like this:
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Button</span>
            <span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.New"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Image</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"20"</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"20"</span><span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Resources/new.png"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
That's fine, except that WPF is all about vectors, and as soon as you start adding
bitmaps, things get pixilated when you show them on your 24" wide-screen monitor.
So, we'll switch the bitmap out into something drawn with the WPF vector system. The
first step is to find or create some vector drawings for use as your button graphics.
You can draw things in Adobe Illustrator and use the Illustrator to xaml plugin (<a title="http://www.mikeswanson.com/XAMLExport/" href="http://www.mikeswanson.com/XAMLExport/">http://www.mikeswanson.com/XAMLExport/</a>),
you can use Expression Studio to draw the items by hand, or you can find a source
on the Internet for nice, friendly toolbar buttons in xaml (<a title="http://www.grafile.com/presentation/Vista_Toolbar_library.html" href="http://www.grafile.com/presentation/Vista_Toolbar_library.html">http://www.grafile.com/presentation/Vista_Toolbar_library.html</a>).
</p>
        <p>
The library that I started with has each icon separated into its own xaml file. Unfortunately,
it also has each item drawn on an 800x600 panel, which doesn't lend itself too well
to scaling onto a square button. So, there is a little work to be done before we can
apply these icons to our buttons. I accomplished the task in Expression Blend. The
first thing I did was generate a resource dictionary for our application. This is
pretty much just a dictionary of useful bits of xaml that you can apply other places
in the application. Do this by adding icons.xaml to the project and editing the App.xaml
to look like this:
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Application.Resources</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">ResourceDictionary</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">ResourceDictionary.MergedDictionaries</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">ResourceDictionary</span>
            <span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Icons.xaml"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ResourceDictionary.MergedDictionaries</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ResourceDictionary</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Application.Resources</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
The next step is to paste in the icons of interest from their respective xaml files.
I guess I could leave them in their individual xaml files and just include each one
as a resource dictionary, but I didn't think of it until now, and it's too late.
</p>
        <p>
In order to use the icons as button images, we store them in the resource dictionary
as ControlTemplates. To do this, create a ControlTemplate tag in the icons.xaml file
and paste in the xaml of the button of interest. 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">ControlTemplate</span>
            <span style="color: #ff0000">x</span>:<span style="color: #ff0000">Key</span>=<span style="color: #0000ff">"New"</span><span style="color: #0000ff">&gt;</span><span style="color: #008000">&lt;!--
Pasted text from the icon of interest --&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ControlTemplate</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
Once you have the ControlTemplate resource setup, the changes to the button definition
are trivial:
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Button</span>
            <span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.New"</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"32"</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"32"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ContentControl</span><span style="color: #ff0000">Template</span>=<span style="color: #0000ff">"{StaticResource
New}"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
Unfortunately, since the icons I used are on an 800x600 canvas, I have to do a little
alteration to make them work on a square button face. First, I wrap the entire icon
in a ViewBox to make it scale nicely. Then, I wrap the original canvas in a square
canvas 345x345 (it seemed like a good number at the time). Finally, I add a render
transform to the original canvas to translate the original image to be centered in
the new, parent canvas. The whole thing looks something like this:
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">ControlTemplate</span>
            <span style="color: #ff0000">x</span>:<span style="color: #ff0000">Key</span>=<span style="color: #0000ff">"New"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Viewbox</span><span style="color: #ff0000">Stretch</span>=<span style="color: #0000ff">"Uniform"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Canvas</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"345"</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"345"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Canvas</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"800"</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"600"</span><span style="color: #ff0000">Canvas</span>.<span style="color: #ff0000">Left</span>=<span style="color: #0000ff">"0"</span><span style="color: #ff0000">Canvas</span>.<span style="color: #ff0000">Top</span>=<span style="color: #0000ff">"0"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Canvas.RenderTransform</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">TransformGroup</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ScaleTransform</span><span style="color: #ff0000">ScaleX</span>=<span style="color: #0000ff">"1"</span><span style="color: #ff0000">ScaleY</span>=<span style="color: #0000ff">"1"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">SkewTransform</span><span style="color: #ff0000">AngleX</span>=<span style="color: #0000ff">"0"</span><span style="color: #ff0000">AngleY</span>=<span style="color: #0000ff">"0"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">RotateTransform</span><span style="color: #ff0000">Angle</span>=<span style="color: #0000ff">"0"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">TranslateTransform</span><span style="color: #ff0000">X</span>=<span style="color: #0000ff">"-220"</span><span style="color: #ff0000">Y</span>=<span style="color: #0000ff">"-157"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">TransformGroup</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Canvas.RenderTransform</span><span style="color: #0000ff">&gt;</span><span style="color: #008000">&lt;!--
Actual drawing code --&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Canvas</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Canvas</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Viewbox</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ControlTemplate</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
That's it. Now, you have classy, WPF-like, xamlized, vector toolbar buttons. Some
of them might be ugly, but they're scalable. I'm sure there is a better way to accomplish
this, but we're one step closer to a real-world Windows-like application using WPF.
We still don't have all of those things that I think should be inherent in a Windows
application (like tooltips, updating of the status bar with command help-text, etc.)
and we can't take advantage of the automatic localization available with the ApplicationCommands
classes since we want to have our own mnemonics for keyboard access to each command.
</p>
        <p>
I think we'll tackle the ToolTips and StatusBar text next. Specifically, we'll take
a look at how to make these items easily localizable so we don't have a bunch of English
phrases locked into our code.
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=564b7c09-d30a-421c-b0e8-c2824a0af0b5" />
      </body>
      <title>WPF Scribble 8</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,564b7c09-d30a-421c-b0e8-c2824a0af0b5.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/06/22/WPFScribble8.aspx</link>
      <pubDate>Fri, 22 Jun 2007 05:36:33 GMT</pubDate>
      <description>&lt;p&gt;
The code for this segment is available at &lt;a href="http://www.cavinconsulting.com/Code/Scribble8.zip"&gt;http://www.cavinconsulting.com/Code/Scribble8.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
By now, we've gotten through most of the Scribble framework (writing a real Windows-like
application using WPF). Of course, I'm sure there are better ways to do what I'm doing,
but that's fine. Here's a short installment on vector icons instead of .bmp/.png icons.
&lt;/p&gt;
&lt;p&gt;
In our previous steps, we displayed our toolbar buttons with something like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.New"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Resources/new.png"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
That's fine, except that WPF is all about vectors, and as soon as you start adding
bitmaps, things get pixilated when you show them on your 24" wide-screen monitor.
So, we'll switch the bitmap out into something drawn with the WPF vector system. The
first step is to find or create some vector drawings for use as your button graphics.
You can draw things in Adobe Illustrator and use the Illustrator to xaml plugin (&lt;a title="http://www.mikeswanson.com/XAMLExport/" href="http://www.mikeswanson.com/XAMLExport/"&gt;http://www.mikeswanson.com/XAMLExport/&lt;/a&gt;),
you can use Expression Studio to draw the items by hand, or you can find a source
on the Internet for nice, friendly toolbar buttons in xaml (&lt;a title="http://www.grafile.com/presentation/Vista_Toolbar_library.html" href="http://www.grafile.com/presentation/Vista_Toolbar_library.html"&gt;http://www.grafile.com/presentation/Vista_Toolbar_library.html&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
The library that I started with has each icon separated into its own xaml file. Unfortunately,
it also has each item drawn on an 800x600 panel, which doesn't lend itself too well
to scaling onto a square button. So, there is a little work to be done before we can
apply these icons to our buttons. I accomplished the task in Expression Blend. The
first thing I did was generate a resource dictionary for our application. This is
pretty much just a dictionary of useful bits of xaml that you can apply other places
in the application. Do this by adding icons.xaml to the project and editing the App.xaml
to look like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Application.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ResourceDictionary&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ResourceDictionary.MergedDictionaries&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ResourceDictionary&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Icons.xaml"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ResourceDictionary.MergedDictionaries&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ResourceDictionary&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Application.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
The next step is to paste in the icons of interest from their respective xaml files.
I guess I could leave them in their individual xaml files and just include each one
as a resource dictionary, but I didn't think of it until now, and it's too late.
&lt;/p&gt;
&lt;p&gt;
In order to use the icons as button images, we store them in the resource dictionary
as ControlTemplates. To do this, create a ControlTemplate tag in the icons.xaml file
and paste in the xaml of the button of interest. 
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ControlTemplate&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Key&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"New"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #008000"&gt;&amp;lt;!--
Pasted text from the icon of interest --&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ControlTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Once you have the ControlTemplate resource setup, the changes to the button definition
are trivial:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.New"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"32"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"32"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ContentControl&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Template&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{StaticResource
New}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Unfortunately, since the icons I used are on an 800x600 canvas, I have to do a little
alteration to make them work on a square button face. First, I wrap the entire icon
in a ViewBox to make it scale nicely. Then, I wrap the original canvas in a square
canvas 345x345 (it seemed like a good number at the time). Finally, I add a render
transform to the original canvas to translate the original image to be centered in
the new, parent canvas. The whole thing looks something like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ControlTemplate&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Key&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"New"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Viewbox&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stretch&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Uniform"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"345"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"345"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"800"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"600"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas.RenderTransform&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TransformGroup&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ScaleTransform&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ScaleX&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ScaleY&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;SkewTransform&lt;/span&gt; &lt;span style="color: #ff0000"&gt;AngleX&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;AngleY&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RotateTransform&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Angle&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TranslateTransform&lt;/span&gt; &lt;span style="color: #ff0000"&gt;X&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"-220"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Y&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"-157"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;TransformGroup&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas.RenderTransform&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #008000"&gt;&amp;lt;!--
Actual drawing code --&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Viewbox&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ControlTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
That's it. Now, you have classy, WPF-like, xamlized, vector toolbar buttons. Some
of them might be ugly, but they're scalable. I'm sure there is a better way to accomplish
this, but we're one step closer to a real-world Windows-like application using WPF.
We still don't have all of those things that I think should be inherent in a Windows
application (like tooltips, updating of the status bar with command help-text, etc.)
and we can't take advantage of the automatic localization available with the ApplicationCommands
classes since we want to have our own mnemonics for keyboard access to each command.
&lt;/p&gt;
&lt;p&gt;
I think we'll tackle the ToolTips and StatusBar text next. Specifically, we'll take
a look at how to make these items easily localizable so we don't have a bunch of English
phrases locked into our code.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=564b7c09-d30a-421c-b0e8-c2824a0af0b5" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,564b7c09-d30a-421c-b0e8-c2824a0af0b5.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=af4f96b5-1115-49ae-97bf-9b6dcc238e75</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,af4f96b5-1115-49ae-97bf-9b6dcc238e75.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,af4f96b5-1115-49ae-97bf-9b6dcc238e75.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=af4f96b5-1115-49ae-97bf-9b6dcc238e75</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This one turned out to be a lot simpler than I had expected. As a result, the code
isn't available. You'll have to do it yourself. 
</p>
        <p>
The question was one of attaching a property of our UI (say, the checked property
of a MenuItem) to one of the clever Resources.Properties values that are taken care
of for us by VS 2005. In our Scribble application, there are a few things we'll want
to persist between sessions (on a per-user basis) such as toolbar visibility and window
size (and maybe window state). 
</p>
        <p>
First, we add values to the Settings class for the values we would like to persist.
You can do this in the properties for the project or by double-clicking on the Settings.settings
class (does anyone know why there are so many ways to accomplish the same task in
VS2005?). 
</p>
        <p>
I added MainWindowWidth and MainWindowHeight as user-scoped, integer values. I also
added InkToolbarVisible, FileToolbarVisible, and StatusbarVisible as bool values.
I set these with reasonable defaults. 
</p>
        <p>
Now, we have to hook these settings up to the properties of the UI. We will use similar
syntax to how we hooked up our Exit command. 
</p>
        <p>
For the window size, we set width and height like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Window</span>
            <span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"{Binding
Source={x:Static scribble:Properties.Settings.Default}, Path=MainWindowHeight, Mode=TwoWay}"</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"{Binding
Source={x:Static scribble:Properties.Settings.Default}, Path=MainWindowWidth, Mode=TwoWay}"</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
For the toolbar and statusbar visibility, we bind the IsChecked property (since that's
where the toolbar and statusbar get their visibility). We set all three values with
the same syntax: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">MenuItem</span>
            <span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_File
Toolbar"</span><span style="color: #ff0000">x</span>:<span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"_viewFileBar"</span><span style="color: #ff0000">IsCheckable</span>=<span style="color: #0000ff">"True"</span><span style="color: #ff0000">IsChecked</span>=<span style="color: #0000ff">"{Binding
Source={x:Static scribble:Properties.Settings.Default}, Path=FileToolbarVisible, Mode=TwoWay}"</span><span style="color: #0000ff">/&gt;</span></pre>
        </blockquote>
        <p>
That's it, except for saving the values when the application closes. To to this, we
override the Windows OnClosing method in the Scribble.xaml.cs file. Here are the contents: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">protected</span>
            <span style="color: #0000ff">override</span>
            <span style="color: #0000ff">void</span> OnClosing(CancelEventArgs
e) { Properties.Settings.Default.Save(); <span style="color: #0000ff">base</span>.OnClosing(e);
} </pre>
        </blockquote>
        <p>
Compile and run a few times, changing the toolbar visibility and the window size.
The application will remember these values each time you run.
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=af4f96b5-1115-49ae-97bf-9b6dcc238e75" />
      </body>
      <title>WPF Scribble 7</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,af4f96b5-1115-49ae-97bf-9b6dcc238e75.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/05/31/WPFScribble7.aspx</link>
      <pubDate>Thu, 31 May 2007 05:14:21 GMT</pubDate>
      <description>&lt;p&gt;
This one turned out to be a lot simpler than I had expected. As a result, the code
isn't available. You'll have to do it yourself. 
&lt;p&gt;
The question was one of attaching a property of our UI (say, the checked property
of a MenuItem) to one of the clever Resources.Properties values that are taken care
of for us by VS 2005. In our Scribble application, there are a few things we'll want
to persist between sessions (on a per-user basis) such as toolbar visibility and window
size (and maybe window state). 
&lt;p&gt;
First, we add values to the Settings class for the values we would like to persist.
You can do this in the properties for the project or by double-clicking on the Settings.settings
class (does anyone know why there are so many ways to accomplish the same task in
VS2005?). 
&lt;p&gt;
I added MainWindowWidth and MainWindowHeight as user-scoped, integer values. I also
added InkToolbarVisible, FileToolbarVisible, and StatusbarVisible as bool values.
I set these with reasonable defaults. 
&lt;p&gt;
Now, we have to hook these settings up to the properties of the UI. We will use similar
syntax to how we hooked up our Exit command. 
&lt;p&gt;
For the window size, we set width and height like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Window&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding
Source={x:Static scribble:Properties.Settings.Default}, Path=MainWindowHeight, Mode=TwoWay}"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding
Source={x:Static scribble:Properties.Settings.Default}, Path=MainWindowWidth, Mode=TwoWay}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
For the toolbar and statusbar visibility, we bind the IsChecked property (since that's
where the toolbar and statusbar get their visibility). We set all three values with
the same syntax: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_File
Toolbar"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_viewFileBar"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsCheckable&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"True"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsChecked&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding
Source={x:Static scribble:Properties.Settings.Default}, Path=FileToolbarVisible, Mode=TwoWay}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
That's it, except for saving the values when the application closes. To to this, we
override the Windows OnClosing method in the Scribble.xaml.cs file. Here are the contents: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnClosing(CancelEventArgs
e) { Properties.Settings.Default.Save(); &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.OnClosing(e);
} &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Compile and run a few times, changing the toolbar visibility and the window size.
The application will remember these values each time you run.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=af4f96b5-1115-49ae-97bf-9b6dcc238e75" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,af4f96b5-1115-49ae-97bf-9b6dcc238e75.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=08213d85-1858-4a73-a4f8-b2e9f91738d8</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,08213d85-1858-4a73-a4f8-b2e9f91738d8.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,08213d85-1858-4a73-a4f8-b2e9f91738d8.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=08213d85-1858-4a73-a4f8-b2e9f91738d8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The source code for this segment is available at <a href="http://www.cavinconsulting.com/Code/Scribble6.zip">http://www.cavinconsulting.com/Code/Scribble6.zip</a>. 
</p>
        <p>
Now that we have a functioning application that loads and saves scribble documents,
it's time to take advantage of some of the new capabilities of WPF. You have to admit,
we haven't really done anything so far that couldn't be accomplished by the old non-declarative
programming practice. Since someone (<a href="http://pluralsight.com/blogs/dbox/">Don
Box</a>) tells us that the "declarative" programming model is "better" than the non-declarative
model, we plan on embracing it whole-heartedly. So, what can we do with it? 
</p>
        <p>
We have already seen some examples in our previous steps. Using the Command= syntax,
we allow the code behind to ignore how that code is being invoked. We use the same
command handler whether File-&gt;New is clicked on a menu or the user clicks the NewFile
button in a toolbar. Big deal. We could have done that before. 
</p>
        <p>
How about this? How about we use some clever WPF tidbits to allow UI elements to manage
other UI elements? Here is an area that has long been a problem. A designer says,
"I want the background color of my button to be the same as what the user chooses
for his font color." Then, a programmer goes into a dim cubicle for a couple of days,
writes some code, drinks some coffee, and viola, a masterpiece of interactive UI is
produced. But, should a bunch of code behind really be necessary for the designer
to apply logic that is strictly UI related? Shouldn't the programmers be busy doing
things like drinking coffee and automatically updating the Customers table whenever
they get a Twitter notification? 
</p>
        <p>
Clearly, the answers are no/yes (sorry, non-parallel sentence construction). No, designers
shouldn't have to wait on programmers to add UI related code. Yes, programmers shouldn't
be spending a bunch of time writing UI related code. Or, at least, that's what we
are told. 
</p>
        <p>
Take our scribble tutorial. Let's add the standard View menu. These menus usually
have entries to turn on or off optional toolbars and status bars. Items that are visible
usually have checks next to them. Items that are invisible usually have no checks
next to them. 
</p>
        <p>
We could implement this by harnessing the MenuItem's Checked and Unchecked events
and writing 3 lines of code to set the appropriate toolbar/statusbar visibility according
to whether the MenuItem just got checked or unchecked. Clearly, this is unacceptable.
The UI is beholden to codebehind for simple UI interaction. We can accomplish this
whole process within XAML, and it's pretty simple (though not as simple as it should
be, given the version of the designer I'm using). 
</p>
        <p>
First, we need to add our view menu: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">MenuItem</span>
            <span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_View"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff"> &lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_File
Toolbar"</span><span style="color: #ff0000">x</span>:<span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"_viewFileBar"</span><span style="color: #ff0000">IsCheckable</span>=<span style="color: #0000ff">"True"</span><span style="color: #ff0000">IsChecked</span>=<span style="color: #0000ff">"True"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff"><font color="#000000"></font>&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_Ink
ToolBar"</span><span style="color: #ff0000">x</span>:<span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"_viewInkBar"</span><span style="color: #ff0000">IsCheckable</span>=<span style="color: #0000ff">"True"</span><span style="color: #ff0000">IsChecked</span>=<span style="color: #0000ff">"True"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"Status
_Bar"</span><span style="color: #ff0000">x</span>:<span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"_viewStatusBar"</span><span style="color: #ff0000">IsCheckable</span>=<span style="color: #0000ff">"True"</span><span style="color: #ff0000">IsChecked</span>=<span style="color: #0000ff">"True"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">MenuItem</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
From here, we need to "bind" the visibility of each toolbar/statusbar to the IsChecked
property of the appropriate MenuItem. Unfortunately, IsChecked is a boolean and the
Visibility property of a MenuItem is a Visibility enum. So, Microsoft was kind enough
to provide us with a mechanism to convert between booleans and visibilities. They
give us a type converter called BooleanToVisibilityConverter. In order to use this
converter, however, we have to put these lines somewhere in the Window element of
our xaml file: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Window.Resources</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff"> &lt;</span>
            <span style="color: #800000">BooleanToVisibilityConverter</span>
            <span style="color: #ff0000">x</span>:<span style="color: #ff0000">Key</span>=<span style="color: #0000ff">"BooleanToVisibilityConverter"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window.Resources</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
Now, we can make use of this converter by adding the following Visibility property
to the toolbars and status bar: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">ToolBar</span>
            <span style="color: #ff0000">Visibility</span>=<span style="color: #0000ff">"{Binding
Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=_viewFileBar}"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ToolBar</span><span style="color: #ff0000">Visibility</span>=<span style="color: #0000ff">"{Binding
Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=_viewInkBar}"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">StatusBar</span><span style="color: #ff0000">DockPanel</span>.<span style="color: #ff0000">Dock</span>=<span style="color: #0000ff">"Bottom"</span><span style="color: #ff0000">Visibility</span>=<span style="color: #0000ff">"{Binding
Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=_viewStatusBar}"</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
That's it. No code. Compile and run, and checking the view items will change the visibility
of the corresponding toolbars or statusbars. The syntax is a little odd, and I'm hoping
that there will be better tool support for this in the future. But, for now, it isn't
that horrible to decipher the {...} syntax. This can be extended to include all sorts
of properties, including font size, background color, whether or not the text flashes,
etc. 
</p>
        <p>
Next time, I'm hoping that we can look at how to attach WPF properties (like IsChecked)
to .NET 2.0 Settings (Properties.Settings) and have them dynamically save and load
so the application remembers the user preferences each time the application starts
and stops.
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=08213d85-1858-4a73-a4f8-b2e9f91738d8" />
      </body>
      <title>WPF Scribble 6</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,08213d85-1858-4a73-a4f8-b2e9f91738d8.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/05/25/WPFScribble6.aspx</link>
      <pubDate>Fri, 25 May 2007 21:55:35 GMT</pubDate>
      <description>&lt;p&gt;
The source code for this segment is available at &lt;a href="http://www.cavinconsulting.com/Code/Scribble6.zip"&gt;http://www.cavinconsulting.com/Code/Scribble6.zip&lt;/a&gt;. 
&lt;p&gt;
Now that we have a functioning application that loads and saves scribble documents,
it's time to take advantage of some of the new capabilities of WPF. You have to admit,
we haven't really done anything so far that couldn't be accomplished by the old non-declarative
programming practice. Since someone (&lt;a href="http://pluralsight.com/blogs/dbox/"&gt;Don
Box&lt;/a&gt;) tells us that the "declarative" programming model is "better" than the non-declarative
model, we plan on embracing it whole-heartedly. So, what can we do with it? 
&lt;p&gt;
We have already seen some examples in our previous steps. Using the Command= syntax,
we allow the code behind to ignore how that code is being invoked. We use the same
command handler whether File-&amp;gt;New is clicked on a menu or the user clicks the NewFile
button in a toolbar. Big deal. We could have done that before. 
&lt;p&gt;
How about this? How about we use some clever WPF tidbits to allow UI elements to manage
other UI elements? Here is an area that has long been a problem. A designer says,
"I want the background color of my button to be the same as what the user chooses
for his font color." Then, a programmer goes into a dim cubicle for a couple of days,
writes some code, drinks some coffee, and viola, a masterpiece of interactive UI is
produced. But, should a bunch of code behind really be necessary for the designer
to apply logic that is strictly UI related? Shouldn't the programmers be busy doing
things like drinking coffee and automatically updating the Customers table whenever
they get a Twitter notification? 
&lt;p&gt;
Clearly, the answers are no/yes (sorry, non-parallel sentence construction). No, designers
shouldn't have to wait on programmers to add UI related code. Yes, programmers shouldn't
be spending a bunch of time writing UI related code. Or, at least, that's what we
are told. 
&lt;p&gt;
Take our scribble tutorial. Let's add the standard View menu. These menus usually
have entries to turn on or off optional toolbars and status bars. Items that are visible
usually have checks next to them. Items that are invisible usually have no checks
next to them. 
&lt;p&gt;
We could implement this by harnessing the MenuItem's Checked and Unchecked events
and writing 3 lines of code to set the appropriate toolbar/statusbar visibility according
to whether the MenuItem just got checked or unchecked. Clearly, this is unacceptable.
The UI is beholden to codebehind for simple UI interaction. We can accomplish this
whole process within XAML, and it's pretty simple (though not as simple as it should
be, given the version of the designer I'm using). 
&lt;p&gt;
First, we need to add our view menu: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_View"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_File
Toolbar"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_viewFileBar"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsCheckable&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"True"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsChecked&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"True"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_Ink
ToolBar"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_viewInkBar"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsCheckable&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"True"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsChecked&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"True"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Status
_Bar"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_viewStatusBar"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsCheckable&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"True"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsChecked&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"True"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
From here, we need to "bind" the visibility of each toolbar/statusbar to the IsChecked
property of the appropriate MenuItem. Unfortunately, IsChecked is a boolean and the
Visibility property of a MenuItem is a Visibility enum. So, Microsoft was kind enough
to provide us with a mechanism to convert between booleans and visibilities. They
give us a type converter called BooleanToVisibilityConverter. In order to use this
converter, however, we have to put these lines somewhere in the Window element of
our xaml file: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Window.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;BooleanToVisibilityConverter&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Key&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"BooleanToVisibilityConverter"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Window.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Now, we can make use of this converter by adding the following Visibility property
to the toolbars and status bar: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ToolBar&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Visibility&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding
Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=_viewFileBar}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ToolBar&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Visibility&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding
Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=_viewInkBar}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StatusBar&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DockPanel&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Dock&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Bottom"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Visibility&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding
Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=_viewStatusBar}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
That's it. No code. Compile and run, and checking the view items will change the visibility
of the corresponding toolbars or statusbars. The syntax is a little odd, and I'm hoping
that there will be better tool support for this in the future. But, for now, it isn't
that horrible to decipher the {...} syntax. This can be extended to include all sorts
of properties, including font size, background color, whether or not the text flashes,
etc. 
&lt;p&gt;
Next time, I'm hoping that we can look at how to attach WPF properties (like IsChecked)
to .NET 2.0 Settings (Properties.Settings) and have them dynamically save and load
so the application remembers the user preferences each time the application starts
and stops.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=08213d85-1858-4a73-a4f8-b2e9f91738d8" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,08213d85-1858-4a73-a4f8-b2e9f91738d8.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=2709e60a-ae15-4842-82e9-3b246029cca9</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,2709e60a-ae15-4842-82e9-3b246029cca9.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,2709e60a-ae15-4842-82e9-3b246029cca9.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=2709e60a-ae15-4842-82e9-3b246029cca9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The source for this segment is available at <a href="http://www.cavinconsulting.com/Code/Scribble5.zip">http://www.cavinconsulting.com/Code/Scribble5.zip</a>. 
</p>
        <p>
The original Scribble tutorial had two options for pen thickness, thick or thin. Since
this is a WPF application, we should probably strive for something a little more modern
with respect to our drawing capabilities. So, let's add toolbar buttons (and menu
items) to allow the user to choose pen thickness and pen color. 
</p>
        <p>
The first thing we need to do is add the commands we'll invoke to our ScribbleCommands
class -- we'll call them PenColor and PenWidth. Add the following lines to ScribbleCommands.cs: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">static</span> RoutedUICommand
penWidth = <span style="color: #0000ff">null</span>; <span style="color: #0000ff">public</span><span style="color: #0000ff">static</span> RoutedUICommand
PenWidth { <span style="color: #0000ff">get</span> { <span style="color: #0000ff">lock</span> (syncRoot)
{ <span style="color: #0000ff">if</span> (<span style="color: #0000ff">null</span> ==
penWidth) { penWidth = <span style="color: #0000ff">new</span> RoutedUICommand( Properties.Resources.PenWidthText,
Properties.Resources.PenWidthName, <span style="color: #0000ff">typeof</span>(ScribbleCommands));
penWidth.InputGestures.Add(<span style="color: #0000ff">new</span> KeyGesture(Key.W,
ModifierKeys.Control | ModifierKeys.Shift)); } } <span style="color: #0000ff">return</span> penWidth;
} } <span style="color: #0000ff">private</span><span style="color: #0000ff">static</span> RoutedUICommand
penColor = <span style="color: #0000ff">null</span>; <span style="color: #0000ff">public</span><span style="color: #0000ff">static</span> RoutedUICommand
PenColor { <span style="color: #0000ff">get</span> { <span style="color: #0000ff">lock</span> (syncRoot)
{ <span style="color: #0000ff">if</span> (<span style="color: #0000ff">null</span> ==
penColor) { penColor = <span style="color: #0000ff">new</span> RoutedUICommand( Properties.Resources.PenColorText,
Properties.Resources.PenColorName, <span style="color: #0000ff">typeof</span>(ScribbleCommands));
penColor.InputGestures.Add(<span style="color: #0000ff">new</span> KeyGesture(Key.C,
ModifierKeys.Control | ModifierKeys.Shift)); } } <span style="color: #0000ff">return</span> penColor;
} } </pre>
        </blockquote>
        <p>
Add the appropriate entries into the Resources string table for PenColorName, PenColorText,
PenWidthName, and PenWidthText. 
</p>
        <p>
Now, we add the command handlers to the window1.xaml.cs file: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">void</span> OnPenWidth(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { NotImplemented(); } <span style="color: #0000ff">public</span><span style="color: #0000ff">void</span> OnPenColor(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { NotImplemented(); }</pre>
        </blockquote>
        <p>
And route the commands to our command handlers in the window1.xaml file: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Window.CommandBindings</span>
            <span style="color: #0000ff">&gt;</span> ...
existing command bindings ... <span style="color: #0000ff">&lt;</span><span style="color: #800000">CommandBinding</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.PenWidth}"</span><span style="color: #ff0000">Executed</span>=<span style="color: #0000ff">"OnPenWidth"</span><span style="color: #ff0000">CanExecute</span>=<span style="color: #0000ff">"CanAlwaysExecute"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">CommandBinding</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.PenColor}"</span><span style="color: #ff0000">Executed</span>=<span style="color: #0000ff">"OnPenColor"</span><span style="color: #ff0000">CanExecute</span>=<span style="color: #0000ff">"CanAlwaysExecute"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">Window.CommandBindings</span><span style="color: #0000ff">&gt;</span></span></pre>
        </blockquote>
        <p>
Finally, we can add some UI elements to trigger our commands. First, we'll add a menu
by adding another MenuItem below the File MenuItem we already have in the window1.xaml
file: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">MenuItem</span>
            <span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_Pen"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.PenWidth}"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.PenColor}"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">MenuItem</span><span style="color: #0000ff">&gt;</span></span></pre>
        </blockquote>
        <p>
Now, we'll add another toolbar with buttons to perform the same actions: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">ToolBar</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Button</span>
            <span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.PenWidth}"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Image</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"20"</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"20"</span><span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Resources/penwidth.png"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.PenColor}"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Image</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"20"</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"20"</span><span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Resources/pencolor.png"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">ToolBar</span><span style="color: #0000ff">&gt;</span></span></span></span></pre>
        </blockquote>
        <p>
That's it for the framework. Now let's handle the commands by adding something to
OnPenColor and OnPenWidth. 
</p>
        <p>
Unfortunately, in their haste to get the .NET Framework 3.0 out the door, Microsoft
did a woefully inadequate job of supporting the sorts of common dialogs a modern programmer
expects. For example, I have yet to find an out of the box .NET 3.0 Color Picker (of
course, it's entirely possible that there is one, I just can't find it). We have two
choices to fix this: 1) p/Invoke the ChooseColor function, or 2) Call the old System.Windows.Forms.ColorDialog.
I'm choosing 2 for the time being. However, since the InkCanvas speaks in Color terms
of System.Windows.Media.Color objects and the color dialog speaks in terms of System.Drawing.Color,
we have some translation to do: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">void</span> OnPenColor(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { System.Windows.Forms.ColorDialog colorDialog = <span style="color: #0000ff">new</span> System.Windows.Forms.ColorDialog();
Color penColor = inkCanvas.DefaultDrawingAttributes.Color; colorDialog.Color = System.Drawing.Color.FromArgb(
penColor.A,penColor.R,penColor.G,penColor.B); <span style="color: #0000ff">if</span> (colorDialog.ShowDialog()
== System.Windows.Forms.DialogResult.OK) { System.Drawing.Color selectedColor = colorDialog.Color;
penColor = Color.FromArgb( selectedColor.A, selectedColor.R, selectedColor.G, selectedColor.B);
inkCanvas.DefaultDrawingAttributes.Color = penColor; } } </pre>
        </blockquote>
        <p>
Not exactly pretty, but functional never the less. Let's move on to the pen width.
First, we'll have to add a form to show the user, allowing them to change the pen
width. Add a new Xaml Window and name it PenWidthForm. In the designer for the PenWidthForm.xaml
(it finally works again since we don't have any internal references to commands).
But now we spend a bunch of time understanding the new layout framework in .NET 3.0.
Gone are the .NET WinForms resizing/anchoring that we finally understand. Now, we
have a whole new collection of layout panels, layout-specific properties, attached
(parent) properties, and the like. It looks like we have our work cut out for us. 
</p>
        <p>
We'll start with attempting a form with a label, text box, ok, and cancel. What could
be easier? 
</p>
        <p>
Here's what I ended up with. You, of course, may choose a different path. I chose
to replace the default with a . From here, I can dock the OK and Cancel buttons to
the bottom and fill the remainder of the area with the payload of the form. The skeleton
looks like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">DockPanel</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">StackPanel</span>
            <span style="color: #ff0000">DockPanel</span>.<span style="color: #ff0000">Dock</span>=<span style="color: #0000ff">"Bottom"</span><span style="color: #ff0000">HorizontalAlignment</span>=<span style="color: #0000ff">"Right"</span><span style="color: #ff0000">Orientation</span>=<span style="color: #0000ff">"Horizontal"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">StackPanel</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff"> &lt;/<span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">DockPanel</span><span style="color: #0000ff">&gt;</span></span></span></span></pre>
        </blockquote>
        <pre>
        </pre>
        <p>
Notice that I dock a to the bottom. This is so I can add buttons to it and they will
stack (horizontally) across the panel. To add the buttons, I do this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">DockPanel</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">StackPanel</span>
            <span style="color: #ff0000">DockPanel</span>.<span style="color: #ff0000">Dock</span>=<span style="color: #0000ff">"Bottom"</span><span style="color: #ff0000">HorizontalAlignment</span>=<span style="color: #0000ff">"Right"</span><span style="color: #ff0000">Orientation</span>=<span style="color: #0000ff">"Horizontal"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span><span style="color: #ff0000">Margin</span>=<span style="color: #0000ff">"4"</span><span style="color: #ff0000">IsDefault</span>=<span style="color: #0000ff">"True"</span><span style="color: #ff0000">TabIndex</span>=<span style="color: #0000ff">"2"</span><span style="color: #0000ff">&gt;</span>_OK<span style="color: #0000ff">&lt;/&lt;
span&gt;<span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span><span style="color: #ff0000">Margin</span>=<span style="color: #0000ff">"4"</span><span style="color: #ff0000">IsCancel</span>=<span style="color: #0000ff">"True"</span><span style="color: #ff0000">TabIndex</span>=<span style="color: #0000ff">"3"</span><span style="color: #0000ff">&gt;</span>_Cancel<span style="color: #0000ff">&lt;/&lt;
span&gt;<span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">StackPanel</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff"> &lt;/<span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">DockPanel</span><span style="color: #0000ff">&gt;</span></span></span></span></span></span></pre>
        </blockquote>
        <p>
Now we can add the payload. For this, I chose to use a  with three rows and two
columns. The left column width will be set to Auto while the right column width is
set to *. The middle row height is set to Auto, while the first and third rows are
set to *. The result of the grid section looks like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Grid</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Grid.ColumnDefinitions</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">ColumnDefinition</span>
            <span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"Auto"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ColumnDefinition</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"*"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">Grid.ColumnDefinitions</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Grid.RowDefinitions</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">RowDefinition</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"*"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">RowDefinition</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"Auto"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">RowDefinition</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"*"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">Grid.RowDefinitions</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Label</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"1"</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Column</span>=<span style="color: #0000ff">"0"</span><span style="color: #ff0000">TabIndex</span>=<span style="color: #0000ff">"0"</span><span style="color: #0000ff">&gt;</span>Pen
_Width<span style="color: #0000ff">&lt;/&lt; span&gt;<span style="color: #800000">Label</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">TextBox</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"1"</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Column</span>=<span style="color: #0000ff">"1"</span><span style="color: #ff0000">TabIndex</span>=<span style="color: #0000ff">"1"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"_penWidthBox"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/&lt;
span&gt;<span style="color: #800000">TextBox</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span></span></span></span></span></span></pre>
        </blockquote>
        <p>
Now, we hook up the event handlers, and the whole thing looks like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">DockPanel</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">StackPanel</span>
            <span style="color: #ff0000">DockPanel</span>.<span style="color: #ff0000">Dock</span>=<span style="color: #0000ff">"Bottom"</span><span style="color: #ff0000">HorizontalAlignment</span>=<span style="color: #0000ff">"Right"</span><span style="color: #ff0000">Orientation</span>=<span style="color: #0000ff">"Horizontal"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span><span style="color: #ff0000">Margin</span>=<span style="color: #0000ff">"4"</span><span style="color: #ff0000">IsDefault</span>=<span style="color: #0000ff">"True"</span><span style="color: #ff0000">TabIndex</span>=<span style="color: #0000ff">"2"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnOk"</span><span style="color: #0000ff">&gt;</span>_OK<span style="color: #0000ff">&lt;/&lt;
span&gt;<span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span><span style="color: #ff0000">Margin</span>=<span style="color: #0000ff">"4"</span><span style="color: #ff0000">IsCancel</span>=<span style="color: #0000ff">"True"</span><span style="color: #ff0000">TabIndex</span>=<span style="color: #0000ff">"3"</span><span style="color: #0000ff">&gt;</span>_Cancel<span style="color: #0000ff">&lt;/&lt;
span&gt;<span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">StackPanel</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Grid.ColumnDefinitions</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ColumnDefinition</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"Auto"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ColumnDefinition</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"*"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">Grid.ColumnDefinitions</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Grid.RowDefinitions</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">RowDefinition</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"*"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">RowDefinition</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"Auto"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">RowDefinition</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"*"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">Grid.RowDefinitions</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Label</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"1"</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Column</span>=<span style="color: #0000ff">"0"</span><span style="color: #ff0000">TabIndex</span>=<span style="color: #0000ff">"0"</span><span style="color: #0000ff">&gt;</span>Pen
_Width<span style="color: #0000ff">&lt;/&lt; span&gt;<span style="color: #800000">Label</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">TextBox</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"1"</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Column</span>=<span style="color: #0000ff">"1"</span><span style="color: #ff0000">TabIndex</span>=<span style="color: #0000ff">"1"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"_penWidthBox"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/&lt;
span&gt;<span style="color: #800000">TextBox</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff"> &lt;/<span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">DockPanel</span><span style="color: #0000ff">&gt;</span></span></span></span></span></span></span></span></span></span></pre>
        </blockquote>
        <p>
We will have to add a few lines of code to the codebehind of the form: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">double</span> _penWidth; <span style="color: #0000ff">public</span><span style="color: #0000ff">double</span> PenWidth
{ <span style="color: #0000ff">get</span> { <span style="color: #0000ff">return</span> _penWidth;
} <span style="color: #0000ff">set</span> { _penWidth = <span style="color: #0000ff">value</span>;
} } <span style="color: #0000ff">public</span> PenWidthForm(<span style="color: #0000ff">double</span> penWidth)
{ _penWidth = penWidth; InitializeComponent(); _penWidthBox.Text = penWidth.ToString();
} <span style="color: #0000ff">public</span><span style="color: #0000ff">void</span> OnOk(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { _penWidth = Convert.ToDouble(_penWidthBox.Text); <span style="color: #0000ff">this</span>.DialogResult
= <span style="color: #0000ff">true</span>; }</pre>
        </blockquote>
        <p>
And we call the form from the PenWidth command: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">void</span> OnPenWidth(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { DrawingAttributes drawingAttributes = inkCanvas.DefaultDrawingAttributes;
PenWidthForm penWidthForm = <span style="color: #0000ff">new</span> PenWidthForm(drawingAttributes.Width); <span style="color: #0000ff">bool</span>?
result = penWidthForm.ShowDialog(); <span style="color: #0000ff">if</span> (result.HasValue
&amp;&amp; result.Value == <span style="color: #0000ff">true</span>) { inkCanvas.DefaultDrawingAttributes.Width
= penWidthForm.PenWidth; inkCanvas.DefaultDrawingAttributes.Height = penWidthForm.PenWidth;
} }</pre>
        </blockquote>
        <p>
That's it. Pretty simple, but the layout mechanism is definitely something I'm going
to have to get used to. Considering that a simple modal dialog box with and OK and
Cancel button is something we write all the time, I would think the mechanism for
writing something like this would be a little more simple than it is. Of course, I
just got really comfortable with the .NET 2.0 layout controls, so maybe I'm a little
slow.
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=2709e60a-ae15-4842-82e9-3b246029cca9" />
      </body>
      <title>WPF Scribble 5</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,2709e60a-ae15-4842-82e9-3b246029cca9.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/05/23/WPFScribble5.aspx</link>
      <pubDate>Wed, 23 May 2007 03:36:03 GMT</pubDate>
      <description>&lt;p&gt;
The source for this segment is available at &lt;a href="http://www.cavinconsulting.com/Code/Scribble5.zip"&gt;http://www.cavinconsulting.com/Code/Scribble5.zip&lt;/a&gt;. 
&lt;p&gt;
The original Scribble tutorial had two options for pen thickness, thick or thin. Since
this is a WPF application, we should probably strive for something a little more modern
with respect to our drawing capabilities. So, let's add toolbar buttons (and menu
items) to allow the user to choose pen thickness and pen color. 
&lt;p&gt;
The first thing we need to do is add the commands we'll invoke to our ScribbleCommands
class -- we'll call them PenColor and PenWidth. Add the following lines to ScribbleCommands.cs: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; RoutedUICommand
penWidth = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; RoutedUICommand
PenWidth { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (syncRoot)
{ &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ==
penWidth) { penWidth = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RoutedUICommand( Properties.Resources.PenWidthText,
Properties.Resources.PenWidthName, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(ScribbleCommands));
penWidth.InputGestures.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; KeyGesture(Key.W,
ModifierKeys.Control | ModifierKeys.Shift)); } } &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; penWidth;
} } &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; RoutedUICommand
penColor = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; RoutedUICommand
PenColor { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (syncRoot)
{ &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ==
penColor) { penColor = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RoutedUICommand( Properties.Resources.PenColorText,
Properties.Resources.PenColorName, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(ScribbleCommands));
penColor.InputGestures.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; KeyGesture(Key.C,
ModifierKeys.Control | ModifierKeys.Shift)); } } &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; penColor;
} } &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Add the appropriate entries into the Resources string table for PenColorName, PenColorText,
PenWidthName, and PenWidthText. 
&lt;p&gt;
Now, we add the command handlers to the window1.xaml.cs file: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnPenWidth(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { NotImplemented(); } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnPenColor(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { NotImplemented(); }&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
And route the commands to our command handlers in the window1.xaml file: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Window.CommandBindings&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; ...
existing command bindings ... &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CommandBinding&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.PenWidth}"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Executed&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnPenWidth"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CanExecute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"CanAlwaysExecute"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CommandBinding&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.PenColor}"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Executed&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnPenColor"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CanExecute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"CanAlwaysExecute"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;Window.CommandBindings&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Finally, we can add some UI elements to trigger our commands. First, we'll add a menu
by adding another MenuItem below the File MenuItem we already have in the window1.xaml
file: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_Pen"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.PenWidth}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.PenColor}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Now, we'll add another toolbar with buttons to perform the same actions: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ToolBar&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.PenWidth}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Resources/penwidth.png"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.PenColor}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"20"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Resources/pencolor.png"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;ToolBar&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
That's it for the framework. Now let's handle the commands by adding something to
OnPenColor and OnPenWidth. 
&lt;p&gt;
Unfortunately, in their haste to get the .NET Framework 3.0 out the door, Microsoft
did a woefully inadequate job of supporting the sorts of common dialogs a modern programmer
expects. For example, I have yet to find an out of the box .NET 3.0 Color Picker (of
course, it's entirely possible that there is one, I just can't find it). We have two
choices to fix this: 1) p/Invoke the ChooseColor function, or 2) Call the old System.Windows.Forms.ColorDialog.
I'm choosing 2 for the time being. However, since the InkCanvas speaks in Color terms
of System.Windows.Media.Color objects and the color dialog speaks in terms of System.Drawing.Color,
we have some translation to do: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnPenColor(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { System.Windows.Forms.ColorDialog colorDialog = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; System.Windows.Forms.ColorDialog();
Color penColor = inkCanvas.DefaultDrawingAttributes.Color; colorDialog.Color = System.Drawing.Color.FromArgb(
penColor.A,penColor.R,penColor.G,penColor.B); &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (colorDialog.ShowDialog()
== System.Windows.Forms.DialogResult.OK) { System.Drawing.Color selectedColor = colorDialog.Color;
penColor = Color.FromArgb( selectedColor.A, selectedColor.R, selectedColor.G, selectedColor.B);
inkCanvas.DefaultDrawingAttributes.Color = penColor; } } &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Not exactly pretty, but functional never the less. Let's move on to the pen width.
First, we'll have to add a form to show the user, allowing them to change the pen
width. Add a new Xaml Window and name it PenWidthForm. In the designer for the PenWidthForm.xaml
(it finally works again since we don't have any internal references to commands).
But now we spend a bunch of time understanding the new layout framework in .NET 3.0.
Gone are the .NET WinForms resizing/anchoring that we finally understand. Now, we
have a whole new collection of layout panels, layout-specific properties, attached
(parent) properties, and the like. It looks like we have our work cut out for us. 
&lt;p&gt;
We'll start with attempting a form with a label, text box, ok, and cancel. What could
be easier? 
&lt;p&gt;
Here's what I ended up with. You, of course, may choose a different path. I chose
to replace the default with a . From here, I can dock the OK and Cancel buttons to
the bottom and fill the remainder of the area with the payload of the form. The skeleton
looks like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;DockPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DockPanel&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Dock&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Bottom"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;HorizontalAlignment&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Right"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Orientation&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Horizontal"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt; &amp;lt;/&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;DockPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;
Notice that I dock a to the bottom. This is so I can add buttons to it and they will
stack (horizontally) across the panel. To add the buttons, I do this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;DockPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DockPanel&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Dock&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Bottom"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;HorizontalAlignment&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Right"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Orientation&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Horizontal"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"4"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsDefault&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"True"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TabIndex&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"2"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;_OK&lt;span style="color: #0000ff"&gt;&amp;lt;/&amp;lt;
span&amp;gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"4"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsCancel&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"True"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TabIndex&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"3"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;_Cancel&lt;span style="color: #0000ff"&gt;&amp;lt;/&amp;lt;
span&amp;gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt; &amp;lt;/&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;DockPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Now we can add the payload. For this, I chose to use a&amp;nbsp; with three rows and two
columns. The left column width will be set to Auto while the right column width is
set to *. The middle row height is set to Auto, while the first and third rows are
set to *. The result of the grid section looks like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ColumnDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Auto"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ColumnDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"*"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"*"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Auto"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"*"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Label&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Column&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TabIndex&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Pen
_Width&lt;span style="color: #0000ff"&gt;&amp;lt;/&amp;lt; span&amp;gt;&lt;span style="color: #800000"&gt;Label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBox&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Column&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TabIndex&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_penWidthBox"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&amp;lt;
span&amp;gt;&lt;span style="color: #800000"&gt;TextBox&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Now, we hook up the event handlers, and the whole thing looks like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;DockPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DockPanel&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Dock&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Bottom"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;HorizontalAlignment&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Right"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Orientation&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Horizontal"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"4"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsDefault&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"True"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TabIndex&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"2"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnOk"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;_OK&lt;span style="color: #0000ff"&gt;&amp;lt;/&amp;lt;
span&amp;gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"4"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;IsCancel&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"True"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TabIndex&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"3"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;_Cancel&lt;span style="color: #0000ff"&gt;&amp;lt;/&amp;lt;
span&amp;gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ColumnDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Auto"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ColumnDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"*"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"*"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Auto"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"*"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Label&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Column&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TabIndex&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Pen
_Width&lt;span style="color: #0000ff"&gt;&amp;lt;/&amp;lt; span&amp;gt;&lt;span style="color: #800000"&gt;Label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBox&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Column&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;TabIndex&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_penWidthBox"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&amp;lt;
span&amp;gt;&lt;span style="color: #800000"&gt;TextBox&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt; &amp;lt;/&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;DockPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
We will have to add a few lines of code to the codebehind of the form: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; _penWidth; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; PenWidth
{ &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _penWidth;
} &lt;span style="color: #0000ff"&gt;set&lt;/span&gt; { _penWidth = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
} } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; PenWidthForm(&lt;span style="color: #0000ff"&gt;double&lt;/span&gt; penWidth)
{ _penWidth = penWidth; InitializeComponent(); _penWidthBox.Text = penWidth.ToString();
} &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnOk(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { _penWidth = Convert.ToDouble(_penWidthBox.Text); &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DialogResult
= &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; }&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
And we call the form from the PenWidth command: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnPenWidth(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { DrawingAttributes drawingAttributes = inkCanvas.DefaultDrawingAttributes;
PenWidthForm penWidthForm = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PenWidthForm(drawingAttributes.Width); &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;?
result = penWidthForm.ShowDialog(); &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (result.HasValue
&amp;amp;&amp;amp; result.Value == &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;) { inkCanvas.DefaultDrawingAttributes.Width
= penWidthForm.PenWidth; inkCanvas.DefaultDrawingAttributes.Height = penWidthForm.PenWidth;
} }&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
That's it. Pretty simple, but the layout mechanism is definitely something I'm going
to have to get used to. Considering that a simple modal dialog box with and OK and
Cancel button is something we write all the time, I would think the mechanism for
writing something like this would be a little more simple than it is. Of course, I
just got really comfortable with the .NET 2.0 layout controls, so maybe I'm a little
slow.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=2709e60a-ae15-4842-82e9-3b246029cca9" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,2709e60a-ae15-4842-82e9-3b246029cca9.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=06092d18-40a4-449b-9a9e-008f3b982ae4</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,06092d18-40a4-449b-9a9e-008f3b982ae4.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,06092d18-40a4-449b-9a9e-008f3b982ae4.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=06092d18-40a4-449b-9a9e-008f3b982ae4</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Source code for this segment is available at <a href="http://www.cavinconsulting.com/Code/Scribble4.zip">http://www.cavinconsulting.com/Code/Scribble4.zip</a>. 
</p>
        <p>
After our first few segments concentrating on framework, it's time to attach some
actions to our commands. We have a decision to make. Do we support multiple open scribble
documents or do we only allow a single item. For now, let's stick with only a single
document. We can add multiple document support later. 
</p>
        <p>
Let's start with Save. We'll use the built-in support from the InkCanvas to load and
save the InkCanvas' strokes collection. I know <a href="http://www.jpboodhoo.com/blog/">Jean-Paul
Boodhoo</a> will lie awake at night due to the lack of separation between presentation
and data. Should a windows control rerally be the keeper of the document data? I have
a feeling we'll revisit this when we want to add multiple views on the same stroke
collection. Of course, we'll see. 
</p>
        <p>
Here's the code I wrote corresponding to the OnFileSaveAs: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">string</span> _filename
= <span style="color: #0000ff">string</span>.Empty;</pre>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">void</span> OnFileSaveAs(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { SaveAs(); } <span style="color: #0000ff">private</span><span style="color: #0000ff">bool</span> SaveAs()
{ SaveFileDialog saveDialog = <span style="color: #0000ff">new</span> SaveFileDialog();
saveDialog.DefaultExt = "<span style="color: #8b0000">.isf</span>"; saveDialog.AddExtension
= <span style="color: #0000ff">true</span>; saveDialog.Title = "<span style="color: #8b0000">Save
Ink</span>"; saveDialog.OverwritePrompt = <span style="color: #0000ff">true</span>;
saveDialog.ValidateNames = <span style="color: #0000ff">true</span>; saveDialog.CheckPathExists
= <span style="color: #0000ff">true</span>; saveDialog.CreatePrompt = <span style="color: #0000ff">false</span>;
saveDialog.Filter = "<span style="color: #8b0000">Ink Files (*.isf)|*.isf|All Files
(*.*)|*.*</span>"; <span style="color: #0000ff">bool</span>? saveResult = saveDialog.ShowDialog(<span style="color: #0000ff">this</span>); <span style="color: #0000ff">if</span> (saveResult.HasValue
&amp;&amp; saveResult.Value == <span style="color: #0000ff">true</span>) { _filename
= saveDialog.FileName; <span style="color: #0000ff">return</span> SaveInk(); } <span style="color: #0000ff">return</span><span style="color: #0000ff">false</span>;
}</pre>
          <pre>
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">bool</span> SaveInk()
{ <span style="color: #0000ff">try</span> { <span style="color: #0000ff">using</span> (FileStream
writer = <span style="color: #0000ff">new</span> FileStream(_filename, FileMode.OpenOrCreate))
{ inkCanvas.Strokes.Save(writer); writer.Close(); } } <span style="color: #0000ff">catch</span> (Exception
ex) { Trace.Fail(ex.Message, ex.StackTrace); <span style="color: #0000ff">return</span><span style="color: #0000ff">false</span>;
} <span style="color: #0000ff">return</span><span style="color: #0000ff">true</span>;
}</pre>
        </blockquote>
        <p>
From here, it's easy to add the functionality for OnFileSave: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">void</span> OnFileSave(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { Save(); } <span style="color: #0000ff">private</span><span style="color: #0000ff">bool</span> Save()
{ <span style="color: #0000ff">if</span> (String.IsNullOrEmpty(_filename)) { <span style="color: #0000ff">return</span> SaveAs();
} <span style="color: #0000ff">else</span> { <span style="color: #0000ff">return</span> SaveInk();
} }</pre>
        </blockquote>
        <p>
Now, let's add OnFileNew: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">bool</span> _dirty
= <span style="color: #0000ff">false</span>;</pre>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">void</span> OnFileNew(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { ClearCanvas(); }</pre>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">void</span> OnStrokeCollected(<span style="color: #0000ff">object</span> sender,
InkCanvasStrokeCollectedEventArgs e) { _dirty = <span style="color: #0000ff">true</span>;
}</pre>
          <pre>
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">bool</span> ClearCanvas()
{ <span style="color: #0000ff">bool</span> eraseAnyway = <span style="color: #0000ff">true</span>; <span style="color: #0000ff">if</span> (_dirty)
{ <span style="color: #008000">// Prompt for save</span> MessageBoxResult result =
MessageBox.Show( "<span style="color: #8b0000">Do you want to save changes?</span>",
"<span style="color: #8b0000">Modifications Detected</span>", MessageBoxButton.YesNoCancel); <span style="color: #0000ff">if</span> ((result
== MessageBoxResult.Cancel) || ((result == MessageBoxResult.Yes) &amp;&amp; (!Save())))
{ eraseAnyway = <span style="color: #0000ff">false</span>; } } <span style="color: #0000ff">if</span> (eraseAnyway)
{ inkCanvas.Strokes.Clear(); _dirty = <span style="color: #0000ff">false</span>; <span style="color: #0000ff">return</span><span style="color: #0000ff">true</span>;
} <span style="color: #0000ff">return</span><span style="color: #0000ff">false</span>;
}</pre>
        </blockquote>
        <p>
Change the InkCanvas declaration in xaml to this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">InkCanvas</span>
            <span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"inkCanvas"</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"2"</span><span style="color: #ff0000">StrokeCollected</span>=<span style="color: #0000ff">"OnStrokeCollected"</span><span style="color: #0000ff">/&gt;</span></pre>
        </blockquote>
        <p>
And finally, OnFileOpen: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">void</span> OnFileOpen(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { <span style="color: #0000ff">if</span> (ClearCanvas()) { OpenFileDialog
openDialog = <span style="color: #0000ff">new</span> OpenFileDialog(); openDialog.DefaultExt
= "<span style="color: #8b0000">.isf</span>"; openDialog.AddExtension = <span style="color: #0000ff">true</span>;
openDialog.Title = "<span style="color: #8b0000">Load Ink</span>"; openDialog.CheckFileExists
= <span style="color: #0000ff">true</span>; openDialog.Filter = "<span style="color: #8b0000">Ink
Files (*.isf)|*.isf|All Files (*.*)|*.*</span>"; <span style="color: #0000ff">bool</span>?
openResult = openDialog.ShowDialog(<span style="color: #0000ff">this</span>); <span style="color: #0000ff">if</span> (openResult.HasValue
&amp;&amp; openResult.Value == <span style="color: #0000ff">true</span>) { _filename
= openDialog.FileName; LoadInk(); } } } <span style="color: #0000ff"></span></pre>
          <pre>
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">bool</span> LoadInk()
{ <span style="color: #0000ff">try</span> { <span style="color: #0000ff">using</span> (FileStream
reader = <span style="color: #0000ff">new</span> FileStream(_filename, FileMode.Open))
{ inkCanvas.Strokes = <span style="color: #0000ff">new</span> StrokeCollection(reader);
reader.Close(); } } <span style="color: #0000ff">catch</span> (Exception ex) { inkCanvas.Strokes.Clear();
_dirty = <span style="color: #0000ff">false</span>; Trace.Fail(ex.Message, ex.StackTrace); <span style="color: #0000ff">return</span><span style="color: #0000ff">false</span>;
} <span style="color: #0000ff">return</span><span style="color: #0000ff">true</span>;
} </pre>
        </blockquote>
        <p>
Pretty straight forward. We're just using the built-in serialization methods of the
InkCanvas to load and save the strokes stored in the canvas. We also attach an event
handler to the Canvas' StrokeCollected event to set the dirty bit (to prompt the user
to save if there are changes). 
</p>
        <p>
Of course, there are some validations we ought to add, and <a href="http://blogs.msdn.com/brada/">Brad
Abrams</a> will get really mad when he sees the <span style="color: #0000ff">catch</span> (Exception
ex) line since you're not supposed to catch System.Exception. But, it loads and save
the canvas so we can take comfort in our ability to create inky masterpieces and be
able to retrieve them sometime in the future.
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=06092d18-40a4-449b-9a9e-008f3b982ae4" />
      </body>
      <title>WPF Scribble 4</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,06092d18-40a4-449b-9a9e-008f3b982ae4.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/05/22/WPFScribble4.aspx</link>
      <pubDate>Tue, 22 May 2007 22:32:26 GMT</pubDate>
      <description>&lt;p&gt;
Source code for this segment is available at &lt;a href="http://www.cavinconsulting.com/Code/Scribble4.zip"&gt;http://www.cavinconsulting.com/Code/Scribble4.zip&lt;/a&gt;. 
&lt;p&gt;
After our first few segments concentrating on framework, it's time to attach some
actions to our commands. We have a decision to make. Do we support multiple open scribble
documents or do we only allow a single item. For now, let's stick with only a single
document. We can add multiple document support later. 
&lt;p&gt;
Let's start with Save. We'll use the built-in support from the InkCanvas to load and
save the InkCanvas' strokes collection. I know &lt;a href="http://www.jpboodhoo.com/blog/"&gt;Jean-Paul
Boodhoo&lt;/a&gt; will lie awake at night due to the lack of separation between presentation
and data. Should a windows control rerally be the keeper of the document data? I have
a feeling we'll revisit this when we want to add multiple views on the same stroke
collection. Of course, we'll see. 
&lt;p&gt;
Here's the code I wrote corresponding to the OnFileSaveAs: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _filename
= &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnFileSaveAs(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { SaveAs(); } &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; SaveAs()
{ SaveFileDialog saveDialog = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SaveFileDialog();
saveDialog.DefaultExt = "&lt;span style="color: #8b0000"&gt;.isf&lt;/span&gt;"; saveDialog.AddExtension
= &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; saveDialog.Title = "&lt;span style="color: #8b0000"&gt;Save
Ink&lt;/span&gt;"; saveDialog.OverwritePrompt = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
saveDialog.ValidateNames = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; saveDialog.CheckPathExists
= &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; saveDialog.CreatePrompt = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
saveDialog.Filter = "&lt;span style="color: #8b0000"&gt;Ink Files (*.isf)|*.isf|All Files
(*.*)|*.*&lt;/span&gt;"; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;? saveResult = saveDialog.ShowDialog(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;); &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (saveResult.HasValue
&amp;amp;&amp;amp; saveResult.Value == &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;) { _filename
= saveDialog.FileName; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; SaveInk(); } &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
}&lt;/pre&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; SaveInk()
{ &lt;span style="color: #0000ff"&gt;try&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (FileStream
writer = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FileStream(_filename, FileMode.OpenOrCreate))
{ inkCanvas.Strokes.Save(writer); writer.Close(); } } &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception
ex) { Trace.Fail(ex.Message, ex.StackTrace); &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
} &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
}&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
From here, it's easy to add the functionality for OnFileSave: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnFileSave(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { Save(); } &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; Save()
{ &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (String.IsNullOrEmpty(_filename)) { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; SaveAs();
} &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; SaveInk();
} }&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Now, let's add OnFileNew: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; _dirty
= &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnFileNew(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { ClearCanvas(); }&lt;/pre&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnStrokeCollected(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
InkCanvasStrokeCollectedEventArgs e) { _dirty = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
}&lt;/pre&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; ClearCanvas()
{ &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; eraseAnyway = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (_dirty)
{ &lt;span style="color: #008000"&gt;// Prompt for save&lt;/span&gt; MessageBoxResult result =
MessageBox.Show( "&lt;span style="color: #8b0000"&gt;Do you want to save changes?&lt;/span&gt;",
"&lt;span style="color: #8b0000"&gt;Modifications Detected&lt;/span&gt;", MessageBoxButton.YesNoCancel); &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((result
== MessageBoxResult.Cancel) || ((result == MessageBoxResult.Yes) &amp;amp;&amp;amp; (!Save())))
{ eraseAnyway = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;; } } &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (eraseAnyway)
{ inkCanvas.Strokes.Clear(); _dirty = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
} &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
}&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Change the InkCanvas declaration in xaml to this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;InkCanvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"inkCanvas"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"2"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;StrokeCollected&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnStrokeCollected"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
And finally, OnFileOpen: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnFileOpen(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ClearCanvas()) { OpenFileDialog
openDialog = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; OpenFileDialog(); openDialog.DefaultExt
= "&lt;span style="color: #8b0000"&gt;.isf&lt;/span&gt;"; openDialog.AddExtension = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
openDialog.Title = "&lt;span style="color: #8b0000"&gt;Load Ink&lt;/span&gt;"; openDialog.CheckFileExists
= &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; openDialog.Filter = "&lt;span style="color: #8b0000"&gt;Ink
Files (*.isf)|*.isf|All Files (*.*)|*.*&lt;/span&gt;"; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;?
openResult = openDialog.ShowDialog(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;); &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (openResult.HasValue
&amp;amp;&amp;amp; openResult.Value == &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;) { _filename
= openDialog.FileName; LoadInk(); } } } &lt;span style="color: #0000ff"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; LoadInk()
{ &lt;span style="color: #0000ff"&gt;try&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (FileStream
reader = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FileStream(_filename, FileMode.Open))
{ inkCanvas.Strokes = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StrokeCollection(reader);
reader.Close(); } } &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex) { inkCanvas.Strokes.Clear();
_dirty = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;; Trace.Fail(ex.Message, ex.StackTrace); &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
} &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
} &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Pretty straight forward. We're just using the built-in serialization methods of the
InkCanvas to load and save the strokes stored in the canvas. We also attach an event
handler to the Canvas' StrokeCollected event to set the dirty bit (to prompt the user
to save if there are changes). 
&lt;p&gt;
Of course, there are some validations we ought to add, and &lt;a href="http://blogs.msdn.com/brada/"&gt;Brad
Abrams&lt;/a&gt; will get really mad when he sees the &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception
ex) line since you're not supposed to catch System.Exception. But, it loads and save
the canvas so we can take comfort in our ability to create inky masterpieces and be
able to retrieve them sometime in the future.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=06092d18-40a4-449b-9a9e-008f3b982ae4" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,06092d18-40a4-449b-9a9e-008f3b982ae4.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=3d63bf56-38c9-4da5-a09b-a1bd828c5c39</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,3d63bf56-38c9-4da5-a09b-a1bd828c5c39.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,3d63bf56-38c9-4da5-a09b-a1bd828c5c39.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=3d63bf56-38c9-4da5-a09b-a1bd828c5c39</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
OK. So the problem with the mnemonics in the custom command was due to an error in
my code. I was explicitly settings the Header attribute as well as binding to our
custom Command class. Since the explicitly set attribute trumps the command's text
property, we didn't get the benefit of the mnemonic under the 'x'. So, if you change
the the contents of Properties.Resources.ExitText to "E_xit" the application will
respond to Alt+F,x just like we want it to. 
</p>
        <p>
Now, I'm not sure how to add a mnemonic after the fact to the built-in ApplicationCommands.X
objects. I can understand a reluctance on the part of the framework developers. 
They have no way to determine which commands will be in the same menu, so they have
no way to guarantee that each menu item has a unique mnemonic. I just wish I could
find the a way to set the keyboard shortcut for the built-in commands without explicitly
setting the text. That would sort of kill the automatic localization aspect of the
built-in commands.
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=3d63bf56-38c9-4da5-a09b-a1bd828c5c39" />
      </body>
      <title>WPF Scribble 3a</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,3d63bf56-38c9-4da5-a09b-a1bd828c5c39.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/05/17/WPFScribble3a.aspx</link>
      <pubDate>Thu, 17 May 2007 08:11:49 GMT</pubDate>
      <description>&lt;p&gt;
OK. So the problem with the mnemonics in the custom command was due to an error in
my code. I was explicitly settings the Header attribute as well as binding to our
custom Command class. Since the explicitly set attribute trumps the command's text
property, we didn't get the benefit of the mnemonic under the 'x'. So, if you change
the the contents of Properties.Resources.ExitText to "E_xit" the application will
respond to Alt+F,x just like we want it to. 
&lt;p&gt;
Now, I'm not sure how to add a mnemonic after the fact to the built-in ApplicationCommands.X
objects. I can understand a reluctance on the part of the framework developers.&amp;nbsp;
They have no way to determine which commands will be in the same menu, so they have
no way to guarantee that each menu item has a unique mnemonic. I just wish I could
find the a way to set the keyboard shortcut for the built-in commands without explicitly
setting the text. That would sort of kill the automatic localization aspect of the
built-in commands.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=3d63bf56-38c9-4da5-a09b-a1bd828c5c39" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,3d63bf56-38c9-4da5-a09b-a1bd828c5c39.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=3adca48e-2b40-4dfc-892f-8e38538e99c6</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,3adca48e-2b40-4dfc-892f-8e38538e99c6.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,3adca48e-2b40-4dfc-892f-8e38538e99c6.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=3adca48e-2b40-4dfc-892f-8e38538e99c6</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The source code for this segment is available at <a href="http://www.cavinconsulting.com/Code/Scribble3.zip">http://www.cavinconsulting.com/Code/Scribble3.zip</a>. 
</p>
        <p>
OK. Last time we took a perfectly understandable (though difficult to localize) version
of a menu and toolbar with mnemonics but without shortcuts and turned it into a more
complex, easier to localize version of a menu and toolbar without mnemonics but with
shortcuts. 
</p>
        <p>
Mnemonics (in the old MFC speak) are the keys you press to activate a menu item from
the keyboard once a menu has focus. Shortcuts are the key sequence you press to activate
a menu item, even if the menu is not active. For example, Ctrl+s is the shortcut usually
corresponding to Save. However, if the File menu is open (dropped down), then the
user can just hit the s key. The mnemonic for a menu item is usually a letter in the
item that is underlined. I say usually because new versions of windows and frameworks
have stopped underlining mnemonics unless you strategically press the Alt key at some
point. I haven't figured out what triggers the visibility of the underlines. I just
know when I open the File menu with Alt+f, the mnemonics are displayed as underlined
characters. When I open the File menu by clicking on it, the mnemonics are not displayed. 
</p>
        <p>
Anyway, that is not the point of this post (mainly because I haven't figured out how
to fix it yet). Instead, the point of this post is to make the Exit menu look like
the rest of the menu items. That is, our current implementation of the file menu looks
like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">MenuItem</span>
            <span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_File"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.New"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.Open"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.Close"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.Save"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.SaveAs"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Separator</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"E_xit"</span><span style="color: #ff0000">InputGestureText</span>=<span style="color: #0000ff">"Alt-F4"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileExit"</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Click
here to exit"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileExit"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">MenuItem</span><span style="color: #0000ff">&gt;</span></span></pre>
        </blockquote>
        <p>
I'd like it to look more like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">MenuItem</span>
            <span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_File"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.New"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.Open"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.Close"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.Save"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.SaveAs"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Separator</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ScribbleCommands.Exit"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/<span style="color: #800000">MenuItem</span><span style="color: #0000ff">&gt;</span></span></pre>
        </blockquote>
        <p>
See the difference? Correct. The second implementation is more consistent. Consistency,
of course, implies readability and maintainability. At least, that's what I've read
a few places, and who am I to contradict? 
</p>
        <p>
First, a little about commands. WPF gives us a bunch of commands to use out-of-the-box.
Some of them are in the ApplicationCommands class, but there are others as well. None
of the built-in commands handles application Exit. I'm not sure why that is. That's
okay, because it gives us the opportunity to learn about writing custom commands.
There is a pretty comprehensive discussion about the Command Pattern and its use in
WPF <a href="http://www.microsoft.com/belux/msdn/nl/community/columns/jdruyts/wpf_commandpattern.mspx">here</a>.
I'll wait while you read it. Done? Good. Now, in order to allow us to implement our
Exit command, we will need to create something that implements ICommand and put that
in between the menu item and the code to be executed. 
</p>
        <p>
First, let's create the command class. We'll do this by creating a new class containing
our custom commands. Create a new class named ScribbleCommands. This class should
look like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">static</span>
            <span style="color: #0000ff">class</span> ScribbleCommands
{ <span style="color: #0000ff">private</span><span style="color: #0000ff">static</span><span style="color: #0000ff">object</span> syncRoot
= <span style="color: #0000ff">new</span><span style="color: #0000ff">object</span>(); <span style="color: #0000ff">private</span><span style="color: #0000ff">static</span> RoutedUICommand
exit = <span style="color: #0000ff">null</span>; <span style="color: #0000ff">public</span><span style="color: #0000ff">static</span> RoutedUICommand
Exit { <span style="color: #0000ff">get</span> { <span style="color: #0000ff">lock</span> (syncRoot)
{ <span style="color: #0000ff">if</span> (<span style="color: #0000ff">null</span> ==
exit) { exit = <span style="color: #0000ff">new</span> RoutedUICommand("<span style="color: #8b0000">Exit</span>",
"<span style="color: #8b0000">Exit</span>", <span style="color: #0000ff">typeof</span>(ScribbleCommands));
exit.InputGestures.Add(<span style="color: #0000ff">new</span> KeyGesture(Key.Q, ModifierKeys.Control));
} } <span style="color: #0000ff">return</span> exit; } } } </pre>
        </blockquote>
        <p>
Notice that this class exposes a static read-only property for the commands we are
allowed to use -- everything else is private. Also, since WPF is inherently multi-threaded,
we lock the null check and creation section so we don't accidentally return two different
instances of the command object. Finally, the two hard-coded "Exit" strings should
be read from the application Resources in order to make this more easily localizable.
After all, that was one of the reasons we started adding these command things in the
first place. This has been implemented with a Resource lookup in the attached source
code. 
</p>
        <p>
Next, we need to hook our new command up to the Exit menu. Unfortunately, here is
where things get more complicated. Sure, it was easy to attach the built-in framework
commands to a button or menu. Connecting your own, however, requires a little more
work. First, we have to add a reference to our own namespace in window1.xaml. I agree,
this seems a bit ridiculous, but open up window1.xaml and add this line to the Window
tag at the top: 
</p>
        <blockquote>
          <pre>
            <span style="color: #ff0000">xmlns</span>:<span style="color: #ff0000">scribble</span>=<span style="color: #0000ff">"clr-namespace:Scribble"</span></pre>
        </blockquote>
        <p>
This tells the compiler that we can use the scribble xml namespace to designate types
in our own assembly. Unfortunately, it has the side-effect of breaking the VS designer. 
You'll now get the big Whoops! window any time you click in the designer. Bummer. 
</p>
        <p>
Next, we have to make the MenuItem point to our Exit command. To do this, change the
Exit MenuItem definition to this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">MenuItem</span>
            <span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"Exit"</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.Exit}"</span><span style="color: #0000ff">/&gt;</span></pre>
        </blockquote>
        <p>
The funny {x: syntax is required to let the compiler know that we are referencing
things in a non-framework location. I'm sure there is more to it than that, but for
our purposes, the description is adequate. 
</p>
        <p>
Finally, we need to tell the application where to route the Exit event. To do this,
add the following line to the Window.CommandBindings list: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">CommandBinding</span>
            <span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"{x:Static
scribble:ScribbleCommands.Exit}"</span></pre>
          <pre>
            <span style="color: #ff0000">Executed</span>=<span style="color: #0000ff">"OnFileExit"</span><span style="color: #ff0000">CanExecute</span>=<span style="color: #0000ff">"CanAlwaysExecute"</span><span style="color: #0000ff">/&gt;</span></pre>
        </blockquote>
        <p>
There you go. Even though the designer is broken, the application compiles and executes
as expected. It's a real bummer about the fragility of the designer, however. I guess
that's why it's still a CTP and not a released product. 
</p>
        <p>
A couple of things to note here: 1) I still haven't figured out how to add mnemonics
to the commands. Adding the '_' character to the command text does not work. 2) Adding
references custom classes can be a painful process. With the buggy support in the
VS designer, you never know until you run the application if the you have the references
correct. If you have them wrong, you get to crawl through a bunch of InnerExceptions
until you find what class failed to load and why. 
</p>
        <p>
What's next? How about actually adding some code to the event handlers and finally
getting a "complete" application?
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=3adca48e-2b40-4dfc-892f-8e38538e99c6" />
      </body>
      <title>WPF Scribble 3</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,3adca48e-2b40-4dfc-892f-8e38538e99c6.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/05/12/WPFScribble3.aspx</link>
      <pubDate>Sat, 12 May 2007 00:45:50 GMT</pubDate>
      <description>&lt;p&gt;
The source code for this segment is available at &lt;a href="http://www.cavinconsulting.com/Code/Scribble3.zip"&gt;http://www.cavinconsulting.com/Code/Scribble3.zip&lt;/a&gt;. 
&lt;p&gt;
OK. Last time we took a perfectly understandable (though difficult to localize) version
of a menu and toolbar with mnemonics but without shortcuts and turned it into a more
complex, easier to localize version of a menu and toolbar without mnemonics but with
shortcuts. 
&lt;p&gt;
Mnemonics (in the old MFC speak) are the keys you press to activate a menu item from
the keyboard once a menu has focus. Shortcuts are the key sequence you press to activate
a menu item, even if the menu is not active. For example, Ctrl+s is the shortcut usually
corresponding to Save. However, if the File menu is open (dropped down), then the
user can just hit the s key. The mnemonic for a menu item is usually a letter in the
item that is underlined. I say usually because new versions of windows and frameworks
have stopped underlining mnemonics unless you strategically press the Alt key at some
point. I haven't figured out what triggers the visibility of the underlines. I just
know when I open the File menu with Alt+f, the mnemonics are displayed as underlined
characters. When I open the File menu by clicking on it, the mnemonics are not displayed. 
&lt;p&gt;
Anyway, that is not the point of this post (mainly because I haven't figured out how
to fix it yet). Instead, the point of this post is to make the Exit menu look like
the rest of the menu items. That is, our current implementation of the file menu looks
like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_File"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.New"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.Open"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.Close"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.Save"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.SaveAs"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Separator&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"E_xit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;InputGestureText&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Alt-F4"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileExit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Click
here to exit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileExit"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
I'd like it to look more like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_File"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.New"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.Open"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.Close"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.Save"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.SaveAs"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Separator&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ScribbleCommands.Exit"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
See the difference? Correct. The second implementation is more consistent. Consistency,
of course, implies readability and maintainability. At least, that's what I've read
a few places, and who am I to contradict? 
&lt;p&gt;
First, a little about commands. WPF gives us a bunch of commands to use out-of-the-box.
Some of them are in the ApplicationCommands class, but there are others as well. None
of the built-in commands handles application Exit. I'm not sure why that is. That's
okay, because it gives us the opportunity to learn about writing custom commands.
There is a pretty comprehensive discussion about the Command Pattern and its use in
WPF &lt;a href="http://www.microsoft.com/belux/msdn/nl/community/columns/jdruyts/wpf_commandpattern.mspx"&gt;here&lt;/a&gt;.
I'll wait while you read it. Done? Good. Now, in order to allow us to implement our
Exit command, we will need to create something that implements ICommand and put that
in between the menu item and the code to be executed. 
&lt;p&gt;
First, let's create the command class. We'll do this by creating a new class containing
our custom commands. Create a new class named ScribbleCommands. This class should
look like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ScribbleCommands
{ &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; syncRoot
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;(); &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; RoutedUICommand
exit = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; RoutedUICommand
Exit { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt; (syncRoot)
{ &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ==
exit) { exit = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RoutedUICommand("&lt;span style="color: #8b0000"&gt;Exit&lt;/span&gt;",
"&lt;span style="color: #8b0000"&gt;Exit&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(ScribbleCommands));
exit.InputGestures.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; KeyGesture(Key.Q, ModifierKeys.Control));
} } &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; exit; } } } &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Notice that this class exposes a static read-only property for the commands we are
allowed to use -- everything else is private. Also, since WPF is inherently multi-threaded,
we lock the null check and creation section so we don't accidentally return two different
instances of the command object. Finally, the two hard-coded "Exit" strings should
be read from the application Resources in order to make this more easily localizable.
After all, that was one of the reasons we started adding these command things in the
first place. This has been implemented with a Resource lookup in the attached source
code. 
&lt;p&gt;
Next, we need to hook our new command up to the Exit menu. Unfortunately, here is
where things get more complicated. Sure, it was easy to attach the built-in framework
commands to a button or menu. Connecting your own, however, requires a little more
work. First, we have to add a reference to our own namespace in window1.xaml. I agree,
this seems a bit ridiculous, but open up window1.xaml and add this line to the Window
tag at the top: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;scribble&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"clr-namespace:Scribble"&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
This tells the compiler that we can use the scribble xml namespace to designate types
in our own assembly. Unfortunately, it has the side-effect of breaking the VS designer.&amp;nbsp;
You'll now get the big Whoops! window any time you click in the designer. Bummer. 
&lt;p&gt;
Next, we have to make the MenuItem point to our Exit command. To do this, change the
Exit MenuItem definition to this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Exit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.Exit}"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
The funny {x: syntax is required to let the compiler know that we are referencing
things in a non-framework location. I'm sure there is more to it than that, but for
our purposes, the description is adequate. 
&lt;p&gt;
Finally, we need to tell the application where to route the Exit event. To do this,
add the following line to the Window.CommandBindings list: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CommandBinding&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{x:Static
scribble:ScribbleCommands.Exit}"&lt;/span&gt; &lt;/pre&gt;&lt;pre&gt;	&lt;span style="color: #ff0000"&gt;Executed&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileExit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CanExecute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"CanAlwaysExecute"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
There you go. Even though the designer is broken, the application compiles and executes
as expected. It's a real bummer about the fragility of the designer, however. I guess
that's why it's still a CTP and not a released product. 
&lt;p&gt;
A couple of things to note here: 1) I still haven't figured out how to add mnemonics
to the commands. Adding the '_' character to the command text does not work. 2) Adding
references custom classes can be a painful process. With the buggy support in the
VS designer, you never know until you run the application if the you have the references
correct. If you have them wrong, you get to crawl through a bunch of InnerExceptions
until you find what class failed to load and why. 
&lt;p&gt;
What's next? How about actually adding some code to the event handlers and finally
getting a "complete" application?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=3adca48e-2b40-4dfc-892f-8e38538e99c6" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,3adca48e-2b40-4dfc-892f-8e38538e99c6.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=043ce348-2395-4964-be3e-ad1a115ce437</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,043ce348-2395-4964-be3e-ad1a115ce437.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,043ce348-2395-4964-be3e-ad1a115ce437.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=043ce348-2395-4964-be3e-ad1a115ce437</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Calibri" size="3">Source for this entry is available at <a href="http://www.cavinconsulting.com/Code/Scribble2.zip">http://www.cavinconsulting.com/Code/Scribble2.zip</a>.</font>
        </p>
        <p>
          <font face="Calibri" size="3">OK. Up to this point we've managed to get an application
running and it actually acts a little like the old MFC <a href="http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx">Scribble</a> tutorial.
Let's continue on this path adding some functionality to the application. The original
tutorial starts out by designing a document class named CScribbleDoc. The goal of
this class is to store a collection of stroke objects in a serializable manner (can
load from and save to disk). This was there to introduce the user to the MFC serialization
framework and also because MFC didn't have anything like the new Ink Canvas control.</font>
        </p>
        <p>
          <font face="Calibri" size="3">Without sparking a religious debate about whether the
data should be stored in a UI object (the InkCanvas) or in a more tier-friendly business
object (CScribbleDoc), I'm going to defer adding the complexity of a document object.
I plan on adding some discussion on the different forms of document serialization
in future installments. Feel free to agree or disagree, this is just the path I plan
on taking.</font>
        </p>
        <p>
          <font face="Calibri" size="3">Today, we add the ability to load and save your scribbled
masterpiece. The first step is to add menu items for New, Open, Save, and Save As.
To do this we could open window1.xaml in the designer select the File menu item and
edit the Items collection in the properties window, but the version of the designer
I have (codename "Cider," November CTP) fails with all sorts of cryptic messages.
So, we resort to editing the xaml by hand. We turn this:</font>
        </p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">MenuItem</span>
            <span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_File"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"E_xit"</span><span style="color: #ff0000">InputGestureText</span>=<span style="color: #0000ff">"Alt+F4"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileExit"</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Click
here to exit"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"FileExit"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">MenuItem</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">MenuItem</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
into this:  
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">MenuItem</span>
            <span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_File"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_New"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileNew"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_Open"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileOpen"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_Close"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileClose"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_Save"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileSave"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"Save
_As..."</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileSaveAs"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Separator</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"E_xit"</span><span style="color: #ff0000">InputGestureText</span>=<span style="color: #0000ff">"Alt+F4"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileExit"</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Click
here to exit"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileExit"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">MenuItem</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
Compiling and running at this point generates a nice looking menu complete with some
of the keyboard shortcuts we all know and love (I love them, anyway -- once you take
the time to learn them, you'll love them, too). I say some of the keyboard shortcuts
because I can use Alt+f,s to save (that's what I have used ever since the old DOS
text editor), but I can't use Ctrl+s. So far as I can tell, there is no way to attach
a shortcut combination directly to a menu item. We will ignore this problem for now... 
</p>
        <p>
Of course, what are menu items without something happening when the user clicks on
them? We can implement these commands using the same event handler mechanism we used
for the Exit menu item. The resulting xaml looks something like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">MenuItem</span>
            <span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_File"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_New"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileNew"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileNew"</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Creates
a new Scribble document"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_Open"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileOpen"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileOpen"</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Opens
an existing Scribble document"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_Close"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileClose"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileClose"</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Closes
the current Scribble document"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_Save"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileSave"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileSave"</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Saves
the current Scribble document"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"Save
_As..."</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileSaveAs"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileSaveAs"</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Saves
the current Scribble document under a different name"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Separator</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"E_xit"</span><span style="color: #ff0000">InputGestureText</span>=<span style="color: #0000ff">"Alt-F4"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileExit"</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Click
here to exit"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileExit"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">MenuItem</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
and the resulting code behind will have this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">void</span> OnFileNew(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { <span style="color: #008000">// TODO:</span> } <span style="color: #0000ff">public</span><span style="color: #0000ff">void</span> OnFileOpen(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { <span style="color: #008000">// TODO:</span> } <span style="color: #0000ff">public</span><span style="color: #0000ff">void</span> OnFileClose(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { <span style="color: #008000">// TODO:</span> } <span style="color: #0000ff">public</span><span style="color: #0000ff">void</span> OnFileSave(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { <span style="color: #008000">// TODO:</span> } <span style="color: #0000ff">public</span><span style="color: #0000ff">void</span> OnFileSaveAs(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { <span style="color: #008000">// TODO:</span> } <span style="color: #0000ff">public</span><span style="color: #0000ff">void</span> OnFileExit(<span style="color: #0000ff">object</span> sender,
RoutedEventArgs e) { <span style="color: #0000ff">this</span>.Close(); } </pre>
        </blockquote>
        <p>
Of course, windows application is complete without a toolbar (except Office 2007 --
it's too good for a toolbar). Most applications have toolbar buttons for common operations.
In our list of operations above, we will have a toolbar button for New, Open, and
Save. In order to add a toolbar to our UI, we will need another row in our master
layout grid. The Height property of the new row will be set to "Auto" and we will
put a ToolbarTray control inside the new row. A ToolbarTray is a WPF control that
allows one or more toolbars to be contained inside of it and allows the standard drag
and drop actions we have all come to expect from windows applications. The interesting
part of window1 xaml looks like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">ToolBarTray</span>
            <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"1"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ToolBar</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Creates
a new Scribble document"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileNew"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileNewButton"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Image</span><span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Resources/new.png"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Opens
an existing Scribble document"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileOpen"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"openFileButton"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Image</span><span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Resources/open.png"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Saves
the current Scribble document"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileSave"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"saveFileButton"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Image</span><span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Resources/save.png"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ToolBar</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ToolBarTray</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
The first thing to note with this code is that the tooltips and event handlers are
duplicated between the menu item and the corresponding toolbar button. The fact that
they use the same event handler makes a lot of sense. After all, how many times do
you want to write the save logic. The duplication of the tooltip, on the other hand,
indicates the likelihood for spelling mistakes and information inconsistencies to
creep into your delivered product. Additionally, life becomes very difficult if you
decide to localize your application to elbonian.  
</p>
        <p>
The second thing to note is that the paths to the icon buttons are paths relative
to the installation directory of the application. This means, in order to deploy the
application, you have to distribute the icons also. In order for life to work well
in the development environment, you'll have to add a build event to copy the resources
to the bin directory. Since this is an unacceptable situation, we will fix this before
addressing the duplication between the menus and toolbars. 
</p>
        <p>
To permanently attach images into our application, I am going to use the Resources
tab under our project properties. Right-click on the project, select Properties and
click on the Resources tab. Click Add Resource and choose Add Existing File. Search
for a bitmap you would like to use for the images on the button (I find the VS2005
image library extremely useful for this), and click Open. This will copy the images
to a Resources directory within your project. It will also auto-generate a class allowing
you to access these images from code. It does not, however, create any way for you
to access these images from the designer. You can, however, mark the newly imported
images as resources for the application by changing the Build Action to Resource.
I'm not sure if this embeds two copies of the same bitmap in the final assembly or
not, but it appears to work. 
</p>
        <p>
Now, we address the code duplication between the menu items and the toolbar buttons.
It turns out that the clever designers of WPF already took this into account and solved
the problem by using a Command Pattern. Without going too deeply into what the Command
Pattern is, let me say that it simplifies the plumbing in between what gets done (like
loading a file) and all of the various ways a user is able to trigger that thing happening
(like File-&gt;Open or clicking on the toolbar). Now, for the Patterns and Practices
purists out there, this explanation is completely inadequate and quite possible slightly
untrue. To them, never mind. To the rest of us, let us see how this applies. 
</p>
        <p>
Instead of hooking up event handlers directly from a button or a menu item to a specific
event handler in our application, the kind folks over at WPF have created a series
of commands we can use to perform the same task. "What's the difference," you might
ask. The difference is that the command handles a whole bunch of the common properties
necessary to be useful from anywhere (button, menu, mouse gesture, key gesture, etc.).
Here's how it works. Instead of defining a button like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Button</span>
            <span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Creates
a new Scribble document"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileNew"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileNewButton"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Image</span><span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Resources/new.png"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
We can define it like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Button</span>
            <span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.New"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Image</span><span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Resources/new.png"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
Who cares? What does this buy us? Well, we can also define the File-&gt;New menu item
like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">MenuItem</span>
            <span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.New"</span><span style="color: #0000ff">/&gt;</span></pre>
        </blockquote>
        <p>
What does that get us? For starters, there is no mention of the literal string "New"
in there anywhere. That's right, the ApplicationCommand.New class takes care of describing
itself to the file menu item and the toolbar button. Moreover, the command class is
multilingual and automatically translates itself depending on the locality of the
machine it is running on. Also, the command responds to standard input gestures (that's
what they like to call keyboard shortcuts now). So, the File-&gt;New menu item proudly
displays Ctrl+N next to it in the menu, and is invoked when the user types Ctrl+N
on the keyboard. 
</p>
        <p>
So, we can rewrite our menu and toolbar sections to look like this: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">DockPanel</span>
            <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"0"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"dockPanel1"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Menu</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"menu1"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_File"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.New"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.Open"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.Close"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.Save"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.SaveAs"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Separator</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"E_xit"</span><span style="color: #ff0000">InputGestureText</span>=<span style="color: #0000ff">"Alt-F4"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileExit"</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Click
here to exit"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"fileExit"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">MenuItem</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Menu</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">DockPanel</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ToolBarTray</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"1"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ToolBar</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.New"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Image</span><span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Resources/new.png"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.Open"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Image</span><span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Resources/open.png"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Button</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"ApplicationCommands.Save"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Image</span><span style="color: #ff0000">Source</span>=<span style="color: #0000ff">"Resources/save.png"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Button</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ToolBar</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ToolBarTray</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
If you compile and run now, you'll see all of the same things you saw before with
a couple of exceptions. First, all of the commands are disabled except the exit command.
Second, there aren't any tooltips. We'll solve this problem shortly. Since tooltips
were one of the main reasons I gave for not using the previous version, I'll do my
best to address that in the next segment. 
</p>
        <p>
In order to attach the application commands to our existing event handlers, we have
to add a mapping between the commands and the methods we will use to execute them.
Just above the first Grid definition, add the following: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Window.CommandBindings</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">CommandBinding</span>
            <span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"New"</span><span style="color: #ff0000">Executed</span>=<span style="color: #0000ff">"OnFileNew"</span><span style="color: #ff0000">CanExecute</span>=<span style="color: #0000ff">"CanAlwaysExecute"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">CommandBinding</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"Open"</span><span style="color: #ff0000">Executed</span>=<span style="color: #0000ff">"OnFileOpen"</span><span style="color: #ff0000">CanExecute</span>=<span style="color: #0000ff">"CanAlwaysExecute"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">CommandBinding</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"Close"</span><span style="color: #ff0000">Executed</span>=<span style="color: #0000ff">"OnFileClose"</span><span style="color: #ff0000">CanExecute</span>=<span style="color: #0000ff">"CanAlwaysExecute"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">CommandBinding</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"Save"</span><span style="color: #ff0000">Executed</span>=<span style="color: #0000ff">"OnFileSave"</span><span style="color: #ff0000">CanExecute</span>=<span style="color: #0000ff">"CanAlwaysExecute"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">CommandBinding</span><span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"SaveAs"</span><span style="color: #ff0000">Executed</span>=<span style="color: #0000ff">"OnFileSaveAs"</span><span style="color: #ff0000">CanExecute</span>=<span style="color: #0000ff">"CanAlwaysExecute"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window.CommandBindings</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
Add the following method to the code behind: 
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">void</span> CanAlwaysExecute(<span style="color: #0000ff">object</span> sender,
CanExecuteRoutedEventArgs e) { e.CanExecute = <span style="color: #0000ff">true</span>;
} </pre>
        </blockquote>
        <p>
These two things are all it takes to hook up our menu items and our commands to our
command handlers. "So what," you ask yourself, "Is this any better than what we had
before?" That's a valid question. On one hand, I can now save my document with Ctrl+s.
On the other hand, I can no longer save my document with Alt+f,s. Great. I've automatically
added keyboard shortcuts (automatically localized to the client machine), but I have
lost the ability to set Access Keys. We've added a level of indirection between the
menus/buttons to the commands that get processed, and we've encapsulated the text
seen by the user into a self-localizing package. Unfortunately, with the additional
layer, I have no idea where to look to add back my keyboard shortcut thing (it used
to be called mnemonic). We may have to skip this for now. 
</p>
        <p>
In the next segment, we'll take a look at making the Exit menu item look like the
rest of the menu items. I just hate inconsistency.
</p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=043ce348-2395-4964-be3e-ad1a115ce437" />
      </body>
      <title>WPF Scribble 2</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,043ce348-2395-4964-be3e-ad1a115ce437.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/05/11/WPFScribble2.aspx</link>
      <pubDate>Fri, 11 May 2007 06:02:03 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Source for this entry is available at &lt;a href="http://www.cavinconsulting.com/Code/Scribble2.zip"&gt;http://www.cavinconsulting.com/Code/Scribble2.zip&lt;/a&gt;.&lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;OK. Up to this point we've managed to get an application
running and it actually acts a little like the old MFC &lt;a href="http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx"&gt;Scribble&lt;/a&gt; tutorial.
Let's continue on this path adding some functionality to the application. The original
tutorial starts out by designing a document class named CScribbleDoc. The goal of
this class is to store a collection of stroke objects in a serializable manner (can
load from and save to disk). This was there to introduce the user to the MFC serialization
framework and also because MFC didn't have anything like the new Ink Canvas control.&lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Without sparking a religious debate about whether the
data should be stored in a UI object (the InkCanvas) or in a more tier-friendly business
object (CScribbleDoc), I'm going to defer adding the complexity of a document object.
I plan on adding some discussion on the different forms of document serialization
in future installments. Feel free to agree or disagree, this is just the path I plan
on taking.&lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Today, we add the ability to load and save your scribbled
masterpiece. The first step is to add menu items for New, Open, Save, and Save As.
To do this we could open window1.xaml in the designer select the File menu item and
edit the Items collection in the properties window, but the version of the designer
I have (codename "Cider," November CTP) fails with all sorts of cryptic messages.
So, we resort to editing the xaml by hand. We turn this:&lt;/font&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_File"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"E_xit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;InputGestureText&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Alt+F4"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileExit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Click
here to exit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"FileExit"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
into this:&amp;nbsp; &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_File"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_New"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileNew"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_Open"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileOpen"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_Close"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileClose"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_Save"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileSave"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Save
_As..."&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileSaveAs"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Separator&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"E_xit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;InputGestureText&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Alt+F4"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileExit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Click
here to exit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileExit"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Compiling and running at this point generates a nice looking menu complete with some
of the keyboard shortcuts we all know and love (I love them, anyway -- once you take
the time to learn them, you'll love them, too). I say some of the keyboard shortcuts
because I can use Alt+f,s to save (that's what I have used ever since the old DOS
text editor), but I can't use Ctrl+s. So far as I can tell, there is no way to attach
a shortcut combination directly to a menu item. We will ignore this problem for now... 
&lt;p&gt;
Of course, what are menu items without something happening when the user clicks on
them? We can implement these commands using the same event handler mechanism we used
for the Exit menu item. The resulting xaml looks something like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_File"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_New"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileNew"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileNew"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Creates
a new Scribble document"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_Open"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileOpen"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileOpen"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Opens
an existing Scribble document"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_Close"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileClose"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileClose"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Closes
the current Scribble document"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_Save"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileSave"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileSave"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Saves
the current Scribble document"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Save
_As..."&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileSaveAs"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileSaveAs"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Saves
the current Scribble document under a different name"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Separator&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"E_xit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;InputGestureText&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Alt-F4"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileExit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Click
here to exit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileExit"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
and the resulting code behind will have this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnFileNew(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { &lt;span style="color: #008000"&gt;// TODO:&lt;/span&gt; } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnFileOpen(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { &lt;span style="color: #008000"&gt;// TODO:&lt;/span&gt; } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnFileClose(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { &lt;span style="color: #008000"&gt;// TODO:&lt;/span&gt; } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnFileSave(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { &lt;span style="color: #008000"&gt;// TODO:&lt;/span&gt; } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnFileSaveAs(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { &lt;span style="color: #008000"&gt;// TODO:&lt;/span&gt; } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnFileExit(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
RoutedEventArgs e) { &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Close(); } &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Of course, windows application is complete without a toolbar (except Office 2007 --
it's too good for a toolbar). Most applications have toolbar buttons for common operations.
In our list of operations above, we will have a toolbar button for New, Open, and
Save. In order to add a toolbar to our UI, we will need another row in our master
layout grid. The Height property of the new row will be set to "Auto" and we will
put a ToolbarTray control inside the new row. A ToolbarTray is a WPF control that
allows one or more toolbars to be contained inside of it and allows the standard drag
and drop actions we have all come to expect from windows applications. The interesting
part of window1 xaml looks like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ToolBarTray&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ToolBar&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Creates
a new Scribble document"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileNew"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileNewButton"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Resources/new.png"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Opens
an existing Scribble document"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileOpen"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"openFileButton"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Resources/open.png"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Saves
the current Scribble document"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileSave"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"saveFileButton"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Resources/save.png"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ToolBar&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ToolBarTray&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
The first thing to note with this code is that the tooltips and event handlers are
duplicated between the menu item and the corresponding toolbar button. The fact that
they use the same event handler makes a lot of sense. After all, how many times do
you want to write the save logic. The duplication of the tooltip, on the other hand,
indicates the likelihood for spelling mistakes and information inconsistencies to
creep into your delivered product. Additionally, life becomes very difficult if you
decide to localize your application to elbonian.&amp;nbsp; 
&lt;p&gt;
The second thing to note is that the paths to the icon buttons are paths relative
to the installation directory of the application. This means, in order to deploy the
application, you have to distribute the icons also. In order for life to work well
in the development environment, you'll have to add a build event to copy the resources
to the bin directory. Since this is an unacceptable situation, we will fix this before
addressing the duplication between the menus and toolbars. 
&lt;p&gt;
To permanently attach images into our application, I am going to use the Resources
tab under our project properties. Right-click on the project, select Properties and
click on the Resources tab. Click Add Resource and choose Add Existing File. Search
for a bitmap you would like to use for the images on the button (I find the VS2005
image library extremely useful for this), and click Open. This will copy the images
to a Resources directory within your project. It will also auto-generate a class allowing
you to access these images from code. It does not, however, create any way for you
to access these images from the designer. You can, however, mark the newly imported
images as resources for the application by changing the Build Action to Resource.
I'm not sure if this embeds two copies of the same bitmap in the final assembly or
not, but it appears to work. 
&lt;p&gt;
Now, we address the code duplication between the menu items and the toolbar buttons.
It turns out that the clever designers of WPF already took this into account and solved
the problem by using a Command Pattern. Without going too deeply into what the Command
Pattern is, let me say that it simplifies the plumbing in between what gets done (like
loading a file) and all of the various ways a user is able to trigger that thing happening
(like File-&amp;gt;Open or clicking on the toolbar). Now, for the Patterns and Practices
purists out there, this explanation is completely inadequate and quite possible slightly
untrue. To them, never mind. To the rest of us, let us see how this applies. 
&lt;p&gt;
Instead of hooking up event handlers directly from a button or a menu item to a specific
event handler in our application, the kind folks over at WPF have created a series
of commands we can use to perform the same task. "What's the difference," you might
ask. The difference is that the command handles a whole bunch of the common properties
necessary to be useful from anywhere (button, menu, mouse gesture, key gesture, etc.).
Here's how it works. Instead of defining a button like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Creates
a new Scribble document"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileNew"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileNewButton"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Resources/new.png"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
We can define it like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.New"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Resources/new.png"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Who cares? What does this buy us? Well, we can also define the File-&amp;gt;New menu item
like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.New"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
What does that get us? For starters, there is no mention of the literal string "New"
in there anywhere. That's right, the ApplicationCommand.New class takes care of describing
itself to the file menu item and the toolbar button. Moreover, the command class is
multilingual and automatically translates itself depending on the locality of the
machine it is running on. Also, the command responds to standard input gestures (that's
what they like to call keyboard shortcuts now). So, the File-&amp;gt;New menu item proudly
displays Ctrl+N next to it in the menu, and is invoked when the user types Ctrl+N
on the keyboard. 
&lt;p&gt;
So, we can rewrite our menu and toolbar sections to look like this: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;DockPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"dockPanel1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Menu&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"menu1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_File"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.New"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.Open"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.Close"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.Save"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.SaveAs"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Separator&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"E_xit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;InputGestureText&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Alt-F4"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileExit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Click
here to exit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"fileExit"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Menu&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;DockPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ToolBarTray&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ToolBar&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.New"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Resources/new.png"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.Open"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Resources/open.png"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ApplicationCommands.Save"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Source&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Resources/save.png"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ToolBar&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ToolBarTray&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
If you compile and run now, you'll see all of the same things you saw before with
a couple of exceptions. First, all of the commands are disabled except the exit command.
Second, there aren't any tooltips. We'll solve this problem shortly. Since tooltips
were one of the main reasons I gave for not using the previous version, I'll do my
best to address that in the next segment. 
&lt;p&gt;
In order to attach the application commands to our existing event handlers, we have
to add a mapping between the commands and the methods we will use to execute them.
Just above the first Grid definition, add the following: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Window.CommandBindings&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CommandBinding&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"New"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Executed&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileNew"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CanExecute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"CanAlwaysExecute"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CommandBinding&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Open"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Executed&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileOpen"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CanExecute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"CanAlwaysExecute"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CommandBinding&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Close"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Executed&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileClose"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CanExecute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"CanAlwaysExecute"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CommandBinding&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Save"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Executed&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileSave"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CanExecute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"CanAlwaysExecute"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;CommandBinding&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"SaveAs"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Executed&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileSaveAs"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CanExecute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"CanAlwaysExecute"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Window.CommandBindings&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Add the following method to the code behind: &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CanAlwaysExecute(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
CanExecuteRoutedEventArgs e) { e.CanExecute = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
} &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
These two things are all it takes to hook up our menu items and our commands to our
command handlers. "So what," you ask yourself, "Is this any better than what we had
before?" That's a valid question. On one hand, I can now save my document with Ctrl+s.
On the other hand, I can no longer save my document with Alt+f,s. Great. I've automatically
added keyboard shortcuts (automatically localized to the client machine), but I have
lost the ability to set Access Keys. We've added a level of indirection between the
menus/buttons to the commands that get processed, and we've encapsulated the text
seen by the user into a self-localizing package. Unfortunately, with the additional
layer, I have no idea where to look to add back my keyboard shortcut thing (it used
to be called mnemonic). We may have to skip this for now. 
&lt;p&gt;
In the next segment, we'll take a look at making the Exit menu item look like the
rest of the menu items. I just hate inconsistency.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=043ce348-2395-4964-be3e-ad1a115ce437" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,043ce348-2395-4964-be3e-ad1a115ce437.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=2c02aa4f-c7ab-4227-98ee-0cf314bfc2d9</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,2c02aa4f-c7ab-4227-98ee-0cf314bfc2d9.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,2c02aa4f-c7ab-4227-98ee-0cf314bfc2d9.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=2c02aa4f-c7ab-4227-98ee-0cf314bfc2d9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
          <font face="Calibri" size="3">Complete source code for this example is available at <a href="http://www.cavinconsulting.com/Code/Scribble1.zip">http://www.cavinconsulting.com/Code/Scribble1.zip</a>.</font>
        </p>
        <p>
          <font face="Calibri" size="3">The first step in the old <a href="http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx">Scribble</a> tutorial
was to create a new application with the AppWizard. With WPF and VS 2005, this means
File-&gt;New-&gt;Project. Choose C#-&gt;.NET Framework 3.0-&gt;Windows Application
(WPF). </font>
        </p>
        <p>
          <font face="Calibri" size="3">
          </font>
          <img src="http://tkfiles.storage.msn.com/x1paDc_gADPsoJYlz6Tzp0wRsEPnnvgp_JVgEj6MyZV1bf77P9KJ0wH70lnVkUMnBD8MQ8lIFpyEbGrUDsqk4sauwuwQepWu9IVARMOjz1UA4w" />
        </p>
        <p>
          <font size="3">
            <font face="Calibri">This creates a single application window with
empty contents, looking something like this:</font> </font>  
</p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Window</span>
            <span style="color: #ff0000">x</span>:<span style="color: #ff0000">Class</span>=<span style="color: #0000ff">"Scribble.Window1"</span><span style="color: #ff0000"> xmlns</span>=<span style="color: #0000ff">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><span style="color: #ff0000"> xmlns</span>:<span style="color: #ff0000">x</span>=<span style="color: #0000ff">"http://schemas.microsoft.com/winfx/2006/xaml"</span><span style="color: #ff0000"> Title</span>=<span style="color: #0000ff">"Scribble"</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"300"</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"300" </span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff"> &lt;</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff"> &lt;/</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <p>
          <font face="Calibri" size="3">If you compile and run at this point, you get a blank
application window which you can close by clicking the ‘X’ in the upper right-hand
corner. </font>
        </p>
        <p>
          <font face="Calibri" size="3">OK. Here I’m going to diverge from the original Scribble
tutorial a little bit and show a simple solution to the task at hand. We’re trying
to make our application accept “ink” input from the user. Back in my day, that took
several steps in the tutorial. Now, however, WPF has an Ink Canvas control. So, our
first implementation will be to use the Ink Canvas. </font>
        </p>
        <p>
          <font face="Calibri" size="3">In the designer view for Window1, open the toolbox and
select the “Common Controls” category. Click the Ink Canvas. Then, click somewhere
on the empty Window1 window. This will insert the Ink Canvas in the window. Unfortunately,
it will also automatically add a whole bunch of formatting xaml that isn’t necessarily
what you want. It will default to a fixed sized with a location based on where you
clicked. In our case, we want the canvas to fill the entire window. So far, I have
found no easy way to do this using the clever visual designer tools in Visual Studio.
The new Expression series of tools make this a little easier, but since we're doing
this in Visual Studio, we'll have to deal with what we're given. We can solve the
problem by editing the code by hand, changing the auto-generated xaml from something
like this: </font>
        </p>
        <blockquote>
          <p>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Window</span>
            <span style="color: #ff0000">x</span>:<span style="color: #ff0000">Class</span>=<span style="color: #0000ff">"Scribble.Window1"</span><br /><span style="color: #ff0000">               
xmlns</span>=<span style="color: #0000ff">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><br /><span style="color: #ff0000">               
xmlns</span>:<span style="color: #ff0000">x</span>=<span style="color: #0000ff">"http://schemas.microsoft.com/winfx/2006/xaml"</span><br /><span style="color: #ff0000">               
Title</span>=<span style="color: #0000ff">"Scribble"</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"300"</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"300"</span><span style="color: #0000ff">&gt;</span><br /><span style="color: #0000ff">    &lt;</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><br /><span style="color: #0000ff">        &lt;</span><span style="color: #800000">InkCanvas</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"250"</span><span style="color: #ff0000">HorizontalAlignment</span>=<span style="color: #0000ff">"Left"</span><span style="color: #ff0000">Margin</span>=<span style="color: #0000ff">"-269,-226,0,0"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"inkCanvas1"</span><span style="color: #ff0000">VerticalAlignment</span>=<span style="color: #0000ff">"Top"</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"292"</span><span style="color: #0000ff">/&gt;</span><br /><span style="color: #0000ff">    &lt;/</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><br /><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window</span><span style="color: #0000ff">&gt;</span></p>
        </blockquote>
        <p>
          <font face="Calibri" size="3">to this:</font>
        </p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Window</span>
            <span style="color: #ff0000">x</span>:<span style="color: #ff0000">Class</span>=<span style="color: #0000ff">"Scribble.Window1"</span><span style="color: #ff0000"> xmlns</span>=<span style="color: #0000ff">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><span style="color: #ff0000"> xmlns</span>:<span style="color: #ff0000">x</span>=<span style="color: #0000ff">"http://schemas.microsoft.com/winfx/2006/xaml"</span><span style="color: #ff0000"> Title</span>=<span style="color: #0000ff">"Scribble"</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"300"</span><span style="color: #ff0000">Width</span>=<span style="color: #0000ff">"300"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff"> &lt;</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff"> &lt;</span><span style="color: #800000">InkCanvas</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"inkCanvas1"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff"> &lt;/</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window</span><span style="color: #0000ff">&gt;</span></pre>
        </blockquote>
        <pre>
          <font size="3">
            <font face="Calibri">Run
and you get something like this: </font>
          </font>
        </pre>
        <p>
          <font face="Calibri" size="3">
          </font>
          <img src="http://tkfiles.storage.msn.com/x1paDc_gADPsoJYlz6Tzp0wRsLjGeT6Om04-uNuvIyR1XrDB5P84-u7ZREEBCxCc2ekajxVPOIPqCcDSbkPr8WqiC0DoI1qiFLLeHddFyG5JuQ" />
        </p>
        <p>
          <font face="Calibri" size="3">OK. That wasn’t so hard, but it doesn’t look like a
windows application. So, let’s make it look like a windows application. Windows applications
have menus, and status bars and things. </font>
        </p>
        <p>
          <font face="Calibri" size="3">To do this, we’ll need someplace to put them (layout
information for the controls). To make it look like a standard windows application,
we’ll make the menu dock at the top and the status bar dock at the bottom. To do this,
we will take advantage of the grid’s layout properties. We’ll add a single column
to our grid and 3 rows. </font>
        </p>
        <p>
          <font face="Calibri" size="3">The top and bottom rows (row 0 and 2) will be set to
automatically resize based on content. That will make them only as tall as their contained
controls. Row 1 will be set to * which means something like fill all the rest. </font>
        </p>
        <p>
          <font face="Calibri" size="3">Here's another place where the VS designer is a little
tedious to use. To add rows and columns to a grid, select the grid in design view.
This is easier said than done. By clicking on the big white area in the window1 designer,
you select the Ink Canvas, not the grid. To select the grid, open the properties window
and select System.Windows.Controls.Grid in the drop-down at the top. Then, in the
properties window choose ColumnDefinitions. Click Add and OK. This will add a single
column to the grid. Then, choose RowDefinitions. Click Add 3 times. for the top and
bottom rows set their Height property to Auto. You may have to type this in by hand.
Then, hit OK. This will change the form's xaml to something like this: </font>
        </p>
        <blockquote>
          <p style="line-height: normal">
            <font size="2">
              <font face="Courier New">
                <span style="color: #0000ff">&lt;</span>
                <span style="color: #800000">Grid</span>
                <span style="color: #0000ff">&gt;</span>
                <br />
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Grid.RowDefinitions</span><span style="color: #0000ff">&gt;</span><br />
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">RowDefinition</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"Auto"</span><span style="color: #0000ff">/&gt;</span><br />
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">RowDefinition</span><span style="color: #0000ff">/&gt;</span><br />
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">RowDefinition</span><span style="color: #ff0000">Height</span>=<span style="color: #0000ff">"Auto"</span><span style="color: #0000ff">/&gt;</span><br />
  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Grid.RowDefinitions</span><span style="color: #0000ff">&gt;</span><br />
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Grid.ColumnDefinitions</span><span style="color: #0000ff">&gt;</span><br />
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">ColumnDefinition</span><span style="color: #0000ff">/&gt;</span><br />
  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Grid.ColumnDefinitions</span><span style="color: #0000ff">&gt;</span><br />
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">InkCanvas</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"inkCanvas1"</span><span style="color: #0000ff">/&gt;</span><br /><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span> </font>
            </font> 
</p>
        </blockquote>
        <p>
          <font face="Calibri" size="3">Now, we have to make the Ink Canvas live in row 1. We
do this by setting its Grid.Row property. Select the canvas in the designer and find
Grid.Row in the property window. Set this value to 1. This will change the InkCanvas
line (above) to this:</font>
        </p>
        <blockquote>
          <p style="line-height: normal">
            <font size="2">
              <font face="Courier New">
                <span style="color: #0000ff">&lt;</span>
                <span style="color: #800000">InkCanvas</span>
                <span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"inkCanvas1"</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"1"</span><span style="color: #0000ff">/&gt;</span></font>
            </font>
          </p>
        </blockquote>
        <p>
          <font face="Calibri" size="3">Next, we add a status bar to the bottom. Here, again,
the VS designer is less than helpful. To add a status bar to the bottom of the window,
you could open the toolbox, open the Menus and Toolbars category, click on Status
Bar, and click somewhere on the window1 design surface. This would place the status
bar with default properties somewhere on the page. It would also add a bunch of grid
related properties that would end looking pretty confusing. I have found it less stressful
to add these sorts of things by hand rather than trying to undo all of the "helpful"
things the designer adds. So, to add a status bar to the bottom row of our grid, add
the following lines directly beneath the InkCanvas line:</font>
        </p>
        <blockquote>
          <p style="line-height: normal">
            <font size="2">
              <font face="Courier New">
                <span style="color: #0000ff">&lt;</span>
                <span style="color: #800000">StatusBar</span>
                <span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"statusBar1"</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"3"</span><span style="color: #0000ff">&gt;</span><br />
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">TextBlock</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"statusText"</span><span style="color: #0000ff">&gt;</span><font color="#000000">Ready</font><span style="color: #0000ff">&lt;/</span><span style="color: #800000">TextBlock</span><span style="color: #0000ff">&gt;</span><br /><span style="color: #0000ff">&lt;/</span><span style="color: #800000">StatusBar</span><span style="color: #0000ff">&gt;</span></font>
            </font>
          </p>
        </blockquote>
        <p>
          <font face="Calibri" size="3">Status bars can contain just about any WPF control (like
progress bars, buttons, pictures, etc.). In the standard case, we only want to host
text in the status bar. In this case, we add a TextBlock control as the status bar’s
content. We name the text block "statusText" with the default value of “Ready”.</font>
        </p>
        <p>
          <font face="Calibri" size="3">Now, let’s add the menu to the top row. First, we have
to add a container for our many Menus. In our case, we'll use a DockPanel to contain
all of our menus. You can add this from the toolbox under the "Common Containers"
category. Click DockPanel and click somewhere in the window . Once again, delete we
delete nearly all of the xaml produced by the designer and change it to this:</font>
        </p>
        <blockquote>
          <pre>
            <font size="2">
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">DockPanel</span>
              <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"0"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"dockPanel1"</span><span style="color: #0000ff">/&gt;</span></font>
          </pre>
        </blockquote>
        <p>
          <font face="Calibri" size="3">Now, we add a Menu to the DockPanel. This is a real
pain to do in the current designer, so typing the xaml directly at this point is probably
more useful.</font>
        </p>
        <blockquote>
          <pre>
            <font size="2">
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">DockPanel</span>
              <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span>=<span style="color: #0000ff">"0"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"dockPanel1"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Menu</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"menu1"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"_File"</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">MenuItem</span><span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"E_xit"</span><span style="color: #0000ff">/&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">MenuItem</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Menu</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">DockPanel</span><span style="color: #0000ff">&gt;</span></font>
          </pre>
        </blockquote>
        <p>
          <font face="Calibri" size="3">The '_' characters in the Header= section indicates
a keyboard shortcut. For those of us who are keyboard users, these shortcuts are invaluable
additions to the accessibility of an application. By placing the '_' in front of the
file menu, a user can activate the file menu by pressing Alt + f. Similarly, the user
can activate the Exit command by pressing the x key when the File menu is active (dropped
down). </font>
        </p>
        <p>
          <font face="Calibri" size="3">If we compile and run, we now have something that resembles
a windows application and has the scribble functionality we want. Now, we need to
make the Exit menu actually do something (like close the application). There are a
variety of ways to accomplish this. For this step, we'll use an Event Handler. We
can do this by changing the Exit MenuItem's definition to this: </font>
        </p>
        <blockquote>
          <pre>
            <font size="2">
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">MenuItem</span>
              <span style="color: #ff0000">Header</span>=<span style="color: #0000ff">"E_xit"</span><span style="color: #ff0000">InputGestureText</span>=<span style="color: #0000ff">"Alt-F4"</span><span style="color: #ff0000">Click</span>=<span style="color: #0000ff">"OnFileExit"</span><span style="color: #ff0000">ToolTip</span>=<span style="color: #0000ff">"Click
here to exit"</span><span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"FileExit"</span><span style="color: #0000ff">/&gt;</span></font>
          </pre>
        </blockquote>
        <p>
          <font face="Calibri" size="3">Next, we need to respond to the click event in code.
We do this by adding the following code to the window1 class in the window1xaml.cs
file:</font>
        </p>
        <blockquote>
          <pre>
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">void</span>
            <font color="#000000">OnFileExit</font>(<span style="color: #0000ff">object</span><font color="#000000">sender</font>,
RoutedEventArgs <font color="#000000">e</font>) <font color="#000000">{</font><span style="color: #0000ff">this</span><font color="#000000">.Close();
}</font></pre>
        </blockquote>
        <p>
          <font face="Calibri" size="3">Now, you should be able to compile and run. The result
will be an application that looks and acts a lot like a regular windows application. <span style="font-size: 11pt; font-family: 'Calibri','sans-serif'">Draw
on the canvas, and when you’re ready to quit, you should be able to use all of the
standard windows commands to exit including: File-&gt;Exit, Red X, Alt+F4, and my
personal favorite Alt+F followed by the x key.</span></font>
        </p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=2c02aa4f-c7ab-4227-98ee-0cf314bfc2d9" />
      </body>
      <title>WPF Scribble 1</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,2c02aa4f-c7ab-4227-98ee-0cf314bfc2d9.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/05/11/WPFScribble1.aspx</link>
      <pubDate>Fri, 11 May 2007 00:34:05 GMT</pubDate>
      <description>&lt;p&gt;
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Complete source code for this example is available at &lt;a href="http://www.cavinconsulting.com/Code/Scribble1.zip"&gt;http://www.cavinconsulting.com/Code/Scribble1.zip&lt;/a&gt;.&lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;The first step in the old &lt;a href="http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx"&gt;Scribble&lt;/a&gt; tutorial
was to create a new application with the AppWizard. With WPF and VS 2005, this means
File-&amp;gt;New-&amp;gt;Project. Choose C#-&amp;gt;.NET Framework 3.0-&amp;gt;Windows Application
(WPF). &lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;&lt;/font&gt;&lt;img src="http://tkfiles.storage.msn.com/x1paDc_gADPsoJYlz6Tzp0wRsEPnnvgp_JVgEj6MyZV1bf77P9KJ0wH70lnVkUMnBD8MQ8lIFpyEbGrUDsqk4sauwuwQepWu9IVARMOjz1UA4w"&gt; 
&lt;p&gt;
&lt;font size="3"&gt;&lt;font face="Calibri"&gt;This creates a single application window with
empty contents, looking something like this:&lt;/font&gt;&amp;nbsp;&lt;/font&gt;&amp;nbsp; &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Window&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Scribble.Window1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt; xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/span&gt; &lt;span style="color: #ff0000"&gt; xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;x&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt; &lt;span style="color: #ff0000"&gt; Title&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Scribble"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300" &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt; &amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Window&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;If you compile and run at this point, you get a blank
application window which you can close by clicking the ‘X’ in the upper right-hand
corner. &lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;OK. Here I’m going to diverge from the original Scribble
tutorial a little bit and show a simple solution to the task at hand. We’re trying
to make our application accept “ink” input from the user. Back in my day, that took
several steps in the tutorial. Now, however, WPF has an Ink Canvas control. So, our
first implementation will be to use the Ink Canvas. &lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;In the designer view for Window1, open the toolbox and
select the “Common Controls” category. Click the Ink Canvas. Then, click somewhere
on the empty Window1 window. This will insert the Ink Canvas in the window. Unfortunately,
it will also automatically add a whole bunch of formatting xaml that isn’t necessarily
what you want. It will default to a fixed sized with a location based on where you
clicked. In our case, we want the canvas to fill the entire window. So far, I have
found no easy way to do this using the clever visual designer tools in Visual Studio.
The new Expression series of tools make this a little easier, but since we're doing
this in Visual Studio, we'll have to deal with what we're given. We can solve the
problem by editing the code by hand, changing the auto-generated xaml from something
like this: &lt;/font&gt; &lt;blockquote&gt; 
&lt;p&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Window&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Scribble.Window1"&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: #ff0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: #ff0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;x&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: #ff0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Title&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Scribble"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;InkCanvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"250"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;HorizontalAlignment&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Left"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"-269,-226,0,0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"inkCanvas1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;VerticalAlignment&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Top"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"292"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Window&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;to this:&lt;/font&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Window&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Scribble.Window1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt; xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/span&gt; &lt;span style="color: #ff0000"&gt; xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;x&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt; &lt;span style="color: #ff0000"&gt; Title&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Scribble"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;InkCanvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"inkCanvas1"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt; &amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Window&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;pre&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Run
and you get something like this: &lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;&lt;/font&gt;&lt;img src="http://tkfiles.storage.msn.com/x1paDc_gADPsoJYlz6Tzp0wRsLjGeT6Om04-uNuvIyR1XrDB5P84-u7ZREEBCxCc2ekajxVPOIPqCcDSbkPr8WqiC0DoI1qiFLLeHddFyG5JuQ"&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;OK. That wasn’t so hard, but it doesn’t look like a
windows application. So, let’s make it look like a windows application. Windows applications
have menus, and status bars and things. &lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;To do this, we’ll need someplace to put them (layout
information for the controls). To make it look like a standard windows application,
we’ll make the menu dock at the top and the status bar dock at the bottom. To do this,
we will take advantage of the grid’s layout properties. We’ll add a single column
to our grid and 3 rows. &lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;The top and bottom rows (row 0 and 2) will be set to
automatically resize based on content. That will make them only as tall as their contained
controls. Row 1 will be set to * which means something like fill all the rest. &lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Here's another place where the VS designer is a little
tedious to use. To add rows and columns to a grid, select the grid in design view.
This is easier said than done. By clicking on the big white area in the window1 designer,
you select the Ink Canvas, not the grid. To select the grid, open the properties window
and select System.Windows.Controls.Grid in the drop-down at the top. Then, in the
properties window choose ColumnDefinitions. Click Add and OK. This will add a single
column to the grid. Then, choose RowDefinitions. Click Add 3 times. for the top and
bottom rows set their Height property to Auto. You may have to type this in by hand.
Then, hit OK. This will change the form's xaml to something like this: &lt;/font&gt; &lt;blockquote&gt; 
&lt;p style="line-height: normal"&gt;
&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Auto"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Auto"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ColumnDefinition&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;InkCanvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"inkCanvas1"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&amp;nbsp;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Now, we have to make the Ink Canvas live in row 1. We
do this by setting its Grid.Row property. Select the canvas in the designer and find
Grid.Row in the property window. Set this value to 1. This will change the InkCanvas
line (above) to this:&lt;/font&gt; &lt;blockquote&gt; 
&lt;p style="line-height: normal"&gt;
&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;InkCanvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"inkCanvas1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Next, we add a status bar to the bottom. Here, again,
the VS designer is less than helpful. To add a status bar to the bottom of the window,
you could open the toolbox, open the Menus and Toolbars category, click on Status
Bar, and click somewhere on the window1 design surface. This would place the status
bar with default properties somewhere on the page. It would also add a bunch of grid
related properties that would end looking pretty confusing. I have found it less stressful
to add these sorts of things by hand rather than trying to undo all of the "helpful"
things the designer adds. So, to add a status bar to the bottom row of our grid, add
the following lines directly beneath the InkCanvas line:&lt;/font&gt; &lt;blockquote&gt; 
&lt;p style="line-height: normal"&gt;
&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StatusBar&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"statusBar1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"3"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"statusText"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;font color="#000000"&gt;Ready&lt;/font&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;StatusBar&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Status bars can contain just about any WPF control (like
progress bars, buttons, pictures, etc.). In the standard case, we only want to host
text in the status bar. In this case, we add a TextBlock control as the status bar’s
content. We name the text block "statusText" with the default value of “Ready”.&lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Now, let’s add the menu to the top row. First, we have
to add a container for our many Menus. In our case, we'll use a DockPanel to contain
all of our menus. You can add this from the toolbox under the "Common Containers"
category. Click DockPanel and click somewhere in the window . Once again, delete we
delete nearly all of the xaml produced by the designer and change it to this:&lt;/font&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;font size="2"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;DockPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"dockPanel1"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/font&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Now, we add a Menu to the DockPanel. This is a real
pain to do in the current designer, so typing the xaml directly at this point is probably
more useful.&lt;/font&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;font size="2"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;DockPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"dockPanel1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Menu&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"menu1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"_File"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"E_xit"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Menu&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;DockPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;The '_' characters in the Header= section indicates
a keyboard shortcut. For those of us who are keyboard users, these shortcuts are invaluable
additions to the accessibility of an application. By placing the '_' in front of the
file menu, a user can activate the file menu by pressing Alt + f. Similarly, the user
can activate the Exit command by pressing the x key when the File menu is active (dropped
down). &lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;If we compile and run, we now have something that resembles
a windows application and has the scribble functionality we want. Now, we need to
make the Exit menu actually do something (like close the application). There are a
variety of ways to accomplish this. For this step, we'll use an Event Handler. We
can do this by changing the Exit MenuItem's definition to this: &lt;/font&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;font size="2"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;MenuItem&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Header&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"E_xit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;InputGestureText&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Alt-F4"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Click&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"OnFileExit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ToolTip&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Click
here to exit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"FileExit"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/font&gt; &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Next, we need to respond to the click event in code.
We do this by adding the following code to the window1 class in the window1xaml.cs
file:&lt;/font&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; &lt;font color="#000000"&gt;OnFileExit&lt;/font&gt;(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; &lt;font color="#000000"&gt;sender&lt;/font&gt;,
RoutedEventArgs &lt;font color="#000000"&gt;e&lt;/font&gt;) &lt;font color="#000000"&gt;{&lt;/font&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;font color="#000000"&gt;.Close();
}&lt;/font&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
&lt;font face="Calibri" size="3"&gt;Now, you should be able to compile and run. The result
will be an application that looks and acts a lot like a regular windows application. &lt;span style="font-size: 11pt; font-family: 'Calibri','sans-serif'"&gt;Draw
on the canvas, and when you’re ready to quit, you should be able to use all of the
standard windows commands to exit including: File-&amp;gt;Exit, Red X, Alt+F4, and my
personal favorite Alt+F followed by the x key.&lt;/span&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=2c02aa4f-c7ab-4227-98ee-0cf314bfc2d9" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,2c02aa4f-c7ab-4227-98ee-0cf314bfc2d9.aspx</comments>
      <category>WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.cavinconsulting.com/Colby/Trackback.aspx?guid=34bd41d2-2276-41f3-ac3e-aa9dbf4cb09b</trackback:ping>
      <pingback:server>http://www.cavinconsulting.com/Colby/pingback.aspx</pingback:server>
      <pingback:target>http://www.cavinconsulting.com/Colby/PermaLink,guid,34bd41d2-2276-41f3-ac3e-aa9dbf4cb09b.aspx</pingback:target>
      <dc:creator>Colby</dc:creator>
      <wfw:comment>http://www.cavinconsulting.com/Colby/CommentView,guid,34bd41d2-2276-41f3-ac3e-aa9dbf4cb09b.aspx</wfw:comment>
      <wfw:commentRss>http://www.cavinconsulting.com/Colby/SyndicationService.asmx/GetEntryCommentsRss?guid=34bd41d2-2276-41f3-ac3e-aa9dbf4cb09b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Calibri" color="#000000" size="3">Long, long ago, Microsoft shipped a
multi-step tutorial with their C++ compiler called scribble (</font>
          <a href="http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx">
            <span style="color: #5f40a8; text-decoration: none; text-underline: none">
              <font face="Calibri" size="3">http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx</font>
            </span>
          </a>
          <font face="Calibri" color="#000000" size="3">).
Scribble is a tiny drawing application wherein the user is allowed to draw freehand
lines on the screen. It had a variety of preferences designed to show off the technology
including: thin or thick pens, multiple open scribble documents (MDI - now, seemingly
defunct), split window view, print, print preview, and email.</font>
        </p>
        <p>
          <font face="Calibri" color="#000000" size="3">The purpose of this tutorial was to
walk a developer through many of the common steps required to build a windows application
using the current release of the compiler. In this case, this included MFC version
something, Microsoft Visual C++ version something, and some version of the Microsoft
Messaging Application Programming Interface (MAPI) in order to email your scribble
masterpiece to friends and family.</font>
        </p>
        <p>
          <font face="Calibri" color="#000000" size="3">In attempting to learn the wealth of
tools and technologies thrown at me recently, I decided it might be wise to take a
step back and go through that old tutorial with a new perspective.</font>
        </p>
        <p>
          <font face="Calibri" color="#000000" size="3">In the entries to follow I hope to walk
through the old Scribble tutorial step by step using WPF as the user interface technology.
I will make all of the code available somehow (we’ll see if live spaces supports it
or not).</font>
        </p>
        <p>
          <font face="Calibri" color="#000000" size="3">If you want to run or modify the project,
you’ll need to install a few things including .NET Framework 3.0, the new version
of the Windows SDK, some form of Visual Studio 2005, and the VS 2005 extensions for
WPF.</font>
        </p>
        <img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=34bd41d2-2276-41f3-ac3e-aa9dbf4cb09b" />
      </body>
      <title>WPF Scribble 0</title>
      <guid isPermaLink="false">http://www.cavinconsulting.com/Colby/PermaLink,guid,34bd41d2-2276-41f3-ac3e-aa9dbf4cb09b.aspx</guid>
      <link>http://www.cavinconsulting.com/Colby/2007/05/10/WPFScribble0.aspx</link>
      <pubDate>Thu, 10 May 2007 23:14:24 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font face="Calibri" color="#000000" size="3"&gt;Long, long ago, Microsoft shipped a
multi-step tutorial with their C++ compiler called scribble (&lt;/font&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx"&gt;&lt;span style="color: #5f40a8; text-decoration: none; text-underline: none"&gt;&lt;font face="Calibri" size="3"&gt;http://msdn2.microsoft.com/en-us/library/aa314520(VS.60).aspx&lt;/font&gt;&lt;/span&gt;&lt;/a&gt;&lt;font face="Calibri" color="#000000" size="3"&gt;).
Scribble is a tiny drawing application wherein the user is allowed to draw freehand
lines on the screen. It had a variety of preferences designed to show off the technology
including: thin or thick pens, multiple open scribble documents (MDI - now, seemingly
defunct), split window view, print, print preview, and email.&lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" color="#000000" size="3"&gt;The purpose of this tutorial was to
walk a developer through many of the common steps required to build a windows application
using the current release of the compiler. In this case, this included MFC version
something, Microsoft Visual C++ version something, and some version of the Microsoft
Messaging Application Programming Interface (MAPI) in order to email your scribble
masterpiece to friends and family.&lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" color="#000000" size="3"&gt;In attempting to learn the wealth of
tools and technologies thrown at me recently, I decided it might be wise to take a
step back and go through that old tutorial with a new perspective.&lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" color="#000000" size="3"&gt;In the entries to follow I hope to walk
through the old Scribble tutorial step by step using WPF as the user interface technology.
I will make all of the code available somehow (we’ll see if live spaces supports it
or not).&lt;/font&gt; 
&lt;p&gt;
&lt;font face="Calibri" color="#000000" size="3"&gt;If you want to run or modify the project,
you’ll need to install a few things including .NET Framework 3.0, the new version
of the Windows SDK, some form of Visual Studio 2005, and the VS 2005 extensions for
WPF.&lt;/font&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.cavinconsulting.com/Colby/aggbug.ashx?id=34bd41d2-2276-41f3-ac3e-aa9dbf4cb09b" /&gt;</description>
      <comments>http://www.cavinconsulting.com/Colby/CommentView,guid,34bd41d2-2276-41f3-ac3e-aa9dbf4cb09b.aspx</comments>
      <category>WPF</category>
    </item>
  </channel>
</rss>