<?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>Adam Salvo (z) - Technology|WPF</title>
    <link>http://blog.salvoz.com/</link>
    <description>newtelligence powered</description>
    <language>en-us</language>
    <copyright>Adam Salvo</copyright>
    <lastBuildDate>Sun, 29 Nov 2009 04:36:28 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.2.8279.16125</generator>
    <managingEditor>adam@salvoz.com</managingEditor>
    <webMaster>adam@salvoz.com</webMaster>
    <item>
      <trackback:ping>http://blog.salvoz.com/Trackback.aspx?guid=0d7b99ff-de61-4178-b031-7f0d32b6af7d</trackback:ping>
      <pingback:server>http://blog.salvoz.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.salvoz.com/PermaLink,guid,0d7b99ff-de61-4178-b031-7f0d32b6af7d.aspx</pingback:target>
      <dc:creator>Adam Salvo</dc:creator>
      <wfw:comment>http://blog.salvoz.com/CommentView,guid,0d7b99ff-de61-4178-b031-7f0d32b6af7d.aspx</wfw:comment>
      <wfw:commentRss>http://blog.salvoz.com/SyndicationService.asmx/GetEntryCommentsRss?guid=0d7b99ff-de61-4178-b031-7f0d32b6af7d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>This post is part of my PDC09 Conference Notes series. These are my raw notes
taken while watching the various session videos from PDC09. Refer to my <a href="http://blog.salvoz.com/2009/11/25/PDC2009Notes.aspx">original
post</a> for some conventions I tried to use.</em>
        </p>
        <p>
PDC Session Link: <a title="Advanced WPF Application Performance Tuning and Analysis" href="http://microsoftpdc.com/Sessions/CL11">Advanced
WPF Application Performance Tuning and Analysis</a></p>
        <p>
This presentation was how you can analyze and tune your WPF applications in 4 key
areas: Memory Usage, Cold Startup Time, Warm Startup Time, and Runtime. There were
several tools used through out the presentation, and the demos were very well done.
I would recommend watching this session to get a better feel for the concepts. The
sample application used for the session is called <a href="http://www.codeplex.com/fishbowl">Fishbowl</a>,
and is a WPF application that lets you work with Facebook in new ways. 
</p>
        <p>
          <strong>Introduction</strong>
        </p>
        <ul>
          <li>
Measure early and measure often</li>
          <li>
Be sure to test on older hardware</li>
          <li>
Grab low hanging fruit</li>
          <li>
Understand perceived performance (i.e. keep the UI responsive during long running
requests)</li>
          <li>
Trade Offs</li>
          <ul>
            <li>
CPU vs. Memory vs. Disk IO</li>
            <li>
Within your application, you may have to pick and choose which features are faster
then others</li>
          </ul>
        </ul>
        <p>
          <strong>Memory Usage</strong>
        </p>
        <ul>
          <li>
150MB of memory was deemed as high for an application like Fishbowl</li>
          <ul>
            <li>
              <em>I found this to be very surprising given how many seemingly simple WPF apps I
have seen using over 200mb of memory at startup. Is memory cheap these days? Yes,
unless you count limited memory on Netbooks, older computers, and virtual machines.</em>
            </li>
          </ul>
          <li>
Process Explorer to view overall memory usage 
</li>
          <li>
Sys-internals VMap to view detailed memory usage by process 
</li>
          <ul>
            <li>
Image: .exe, .dll, etc</li>
            <li>
Heap: Pure managed applications should have lower native heap then managed heap. You
will always have some native heap, as some CLR stuff uses native memory, like the
render thread. Images (pictures) are also stored in the native heap and are one source
of high native heap usage. 
</li>
            <li>
Managed: 
</li>
          </ul>
          <li>
The cause of the high memory usage was the use of 114 images for the startup animation. 
</li>
          <ul>
            <li>
# of images * width in pixles * hieght in pixles * 4 (32 bit color) = memory usage</li>
            <li>
114 * 272 * 294 * 4 = 34.7MB</li>
            <li>
The actual cause turned out to be that the start view was not being disposed after
it was finished, so the images remained in memory. 
</li>
          </ul>
          <li>
SaciTech Memory Profiler on memProfiler.com</li>
          <ul>
            <li>
Costs money</li>
            <li>
WPF perf team uses this tool internally</li>
            <li>
Lets you do snapshots so you can compare memory usage over time</li>
            <li>
You can drill down by object type, as well as what is holding onto the reference for
a particular object.</li>
          </ul>
          <li>
Element count (virtualization) is another pain point</li>
        </ul>
        <p>
          <strong>Cold Start</strong>
        </p>
        <ul>
          <li>
Cold start is impacting most by Disk IO</li>
          <li>
Windows Performance Tool Kit or Windows SDK?</li>
          <ul>
            <li>
xperf command line tool (there is a PDC session on xpef and ETW)</li>
            <li>
Event Tracing for windows (ETW): Add ETW statements to your app and profile with xperf</li>
            <li>
Demo showed a batch file to start up xperf</li>
            <li>
Look for for highest number of reads</li>
          </ul>
          <li>
Remove unneeded dll references</li>
          <ul>
            <li>
System.Windows.Forms and System.Windows.Drawing shouldn’t be needed in pure WPF application</li>
          </ul>
          <li>
If you are using only one or two methods from a dll, you could merge it into your
application</li>
          <ul>
            <li>
You can use Scitech Mem Profiler to see how many types for dll to see you can eliminate
or merge</li>
          </ul>
          <li>
If you are using a managed API that is dealing with win32 api’s, you could add p/Inovke’s
to your code to eliminate an extra dll. 
</li>
          <li>
Be sure to test in release mode with no debuggers attached</li>
          <li>
You can use NGen to speed up cold start, but it might slow down warm start</li>
        </ul>
        <p>
          <strong>Warm Start</strong>
        </p>
        <ul>
          <li>
Warm Start is CPU bound, so you will see high CPU usage. There should also be lower
disk IO then cold start.</li>
          <li>
If you see low CPU usage, there might be something blocking, like network access (using
xperf again)</li>
          <li>
CPU Profiler</li>
          <ul>
            <li>
Comes with Team Suite</li>
          </ul>
          <li>
WPF Perf</li>
          <ul>
            <li>
Part of Windows Performance tool kit</li>
            <li>
Check item count, is virtualization enabled. Sometimes virtualization can’t be used,
like when list element height is dynamic, which would screw up the scroll bar 
</li>
          </ul>
        </ul>
        <p>
          <strong>Runtime</strong>
        </p>
        <ul>
          <li>
More WPF Perf usage</li>
          <li>
Trouble shoot jerky animations</li>
          <ul>
            <li>
Layout vs. Rendering</li>
          </ul>
          <li>
Pererator Tool:</li>
          <ul>
            <li>
Review hardware IRT’s. In the example, 20 hardware IRTs was too high.</li>
          </ul>
          <li>
Problem was traced to drop shadow animation. Solution was to create two elements,
one with and one without drop shadow, then toggle visibility</li>
          <li>
Other stuff</li>
          <ul>
            <li>
Don’t block on the UI thread</li>
            <li>
Virtualization when needed</li>
            <li>
Freeze your freezables</li>
            <ul>
              <li>
No change notification call backs</li>
            </ul>
            <li>
Hardware vs. Software</li>
            <ul>
              <li>
use RenderCapabilities.Tier to determine when you should dial down visual effects.</li>
            </ul>
          </ul>
        </ul>
        <img width="0" height="0" src="http://blog.salvoz.com/aggbug.ashx?id=0d7b99ff-de61-4178-b031-7f0d32b6af7d" />
        <br />
        <hr />
This weblog is sponsored by <a href="http://www.salvoz.com">Adam Salvo</a>. 
</body>
      <title>PDC09 – CL11: Advanced WPF Application Performance Tuning and Analysis</title>
      <guid isPermaLink="false">http://blog.salvoz.com/PermaLink,guid,0d7b99ff-de61-4178-b031-7f0d32b6af7d.aspx</guid>
      <link>http://blog.salvoz.com/2009/11/29/PDC09CL11AdvancedWPFApplicationPerformanceTuningAndAnalysis.aspx</link>
      <pubDate>Sun, 29 Nov 2009 04:36:28 GMT</pubDate>
      <description>&lt;p&gt;
&lt;em&gt;This post is part of my PDC09 Conference Notes series. These are my raw notes
taken while watching the various session videos from PDC09. Refer to my &lt;a href="http://blog.salvoz.com/2009/11/25/PDC2009Notes.aspx"&gt;original
post&lt;/a&gt; for some conventions I tried to use.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
PDC Session Link: &lt;a title="Advanced WPF Application Performance Tuning and Analysis" href="http://microsoftpdc.com/Sessions/CL11"&gt;Advanced
WPF Application Performance Tuning and Analysis&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
This presentation was how you can analyze and tune your WPF applications in 4 key
areas: Memory Usage, Cold Startup Time, Warm Startup Time, and Runtime. There were
several tools used through out the presentation, and the demos were very well done.
I would recommend watching this session to get a better feel for the concepts. The
sample application used for the session is called &lt;a href="http://www.codeplex.com/fishbowl"&gt;Fishbowl&lt;/a&gt;,
and is a WPF application that lets you work with Facebook in new ways. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Measure early and measure often&lt;/li&gt;
&lt;li&gt;
Be sure to test on older hardware&lt;/li&gt;
&lt;li&gt;
Grab low hanging fruit&lt;/li&gt;
&lt;li&gt;
Understand perceived performance (i.e. keep the UI responsive during long running
requests)&lt;/li&gt;
&lt;li&gt;
Trade Offs&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
CPU vs. Memory vs. Disk IO&lt;/li&gt;
&lt;li&gt;
Within your application, you may have to pick and choose which features are faster
then others&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Memory Usage&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
150MB of memory was deemed as high for an application like Fishbowl&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;I found this to be very surprising given how many seemingly simple WPF apps I
have seen using over 200mb of memory at startup. Is memory cheap these days? Yes,
unless you count limited memory on Netbooks, older computers, and virtual machines.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Process Explorer to view overall memory usage 
&lt;/li&gt;
&lt;li&gt;
Sys-internals VMap to view detailed memory usage by process 
&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
Image: .exe, .dll, etc&lt;/li&gt;
&lt;li&gt;
Heap: Pure managed applications should have lower native heap then managed heap. You
will always have some native heap, as some CLR stuff uses native memory, like the
render thread. Images (pictures) are also stored in the native heap and are one source
of high native heap usage. 
&lt;/li&gt;
&lt;li&gt;
Managed: 
&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
The cause of the high memory usage was the use of 114 images for the startup animation. 
&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
# of images * width in pixles * hieght in pixles * 4 (32 bit color) = memory usage&lt;/li&gt;
&lt;li&gt;
114 * 272 * 294 * 4 = 34.7MB&lt;/li&gt;
&lt;li&gt;
The actual cause turned out to be that the start view was not being disposed after
it was finished, so the images remained in memory. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
SaciTech Memory Profiler on memProfiler.com&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
Costs money&lt;/li&gt;
&lt;li&gt;
WPF perf team uses this tool internally&lt;/li&gt;
&lt;li&gt;
Lets you do snapshots so you can compare memory usage over time&lt;/li&gt;
&lt;li&gt;
You can drill down by object type, as well as what is holding onto the reference for
a particular object.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Element count (virtualization) is another pain point&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Cold Start&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Cold start is impacting most by Disk IO&lt;/li&gt;
&lt;li&gt;
Windows Performance Tool Kit or Windows SDK?&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
xperf command line tool (there is a PDC session on xpef and ETW)&lt;/li&gt;
&lt;li&gt;
Event Tracing for windows (ETW): Add ETW statements to your app and profile with xperf&lt;/li&gt;
&lt;li&gt;
Demo showed a batch file to start up xperf&lt;/li&gt;
&lt;li&gt;
Look for for highest number of reads&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Remove unneeded dll references&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
System.Windows.Forms and System.Windows.Drawing shouldn’t be needed in pure WPF application&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
If you are using only one or two methods from a dll, you could merge it into your
application&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
You can use Scitech Mem Profiler to see how many types for dll to see you can eliminate
or merge&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
If you are using a managed API that is dealing with win32 api’s, you could add p/Inovke’s
to your code to eliminate an extra dll. 
&lt;/li&gt;
&lt;li&gt;
Be sure to test in release mode with no debuggers attached&lt;/li&gt;
&lt;li&gt;
You can use NGen to speed up cold start, but it might slow down warm start&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Warm Start&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Warm Start is CPU bound, so you will see high CPU usage. There should also be lower
disk IO then cold start.&lt;/li&gt;
&lt;li&gt;
If you see low CPU usage, there might be something blocking, like network access (using
xperf again)&lt;/li&gt;
&lt;li&gt;
CPU Profiler&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
Comes with Team Suite&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
WPF Perf&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
Part of Windows Performance tool kit&lt;/li&gt;
&lt;li&gt;
Check item count, is virtualization enabled. Sometimes virtualization can’t be used,
like when list element height is dynamic, which would screw up the scroll bar 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Runtime&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
More WPF Perf usage&lt;/li&gt;
&lt;li&gt;
Trouble shoot jerky animations&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
Layout vs. Rendering&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Pererator Tool:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
Review hardware IRT’s. In the example, 20 hardware IRTs was too high.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Problem was traced to drop shadow animation. Solution was to create two elements,
one with and one without drop shadow, then toggle visibility&lt;/li&gt;
&lt;li&gt;
Other stuff&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
Don’t block on the UI thread&lt;/li&gt;
&lt;li&gt;
Virtualization when needed&lt;/li&gt;
&lt;li&gt;
Freeze your freezables&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
No change notification call backs&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Hardware vs. Software&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;
use RenderCapabilities.Tier to determine when you should dial down visual effects.&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://blog.salvoz.com/aggbug.ashx?id=0d7b99ff-de61-4178-b031-7f0d32b6af7d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
This weblog is sponsored by &lt;a href="http://www.salvoz.com"&gt;Adam Salvo&lt;/a&gt;. </description>
      <comments>http://blog.salvoz.com/CommentView,guid,0d7b99ff-de61-4178-b031-7f0d32b6af7d.aspx</comments>
      <category>Technology/Conference Notes</category>
      <category>Technology/WPF</category>
    </item>
    <item>
      <trackback:ping>http://blog.salvoz.com/Trackback.aspx?guid=5910971b-e00d-46cb-b433-d1239489d651</trackback:ping>
      <pingback:server>http://blog.salvoz.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.salvoz.com/PermaLink,guid,5910971b-e00d-46cb-b433-d1239489d651.aspx</pingback:target>
      <dc:creator>Adam Salvo</dc:creator>
      <wfw:comment>http://blog.salvoz.com/CommentView,guid,5910971b-e00d-46cb-b433-d1239489d651.aspx</wfw:comment>
      <wfw:commentRss>http://blog.salvoz.com/SyndicationService.asmx/GetEntryCommentsRss?guid=5910971b-e00d-46cb-b433-d1239489d651</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>This post is part of my PDC09 Conference Notes series. These are my raw notes
taken while watching the various session videos from PDC09. Refer to my <a href="http://blog.salvoz.com/2009/11/25/PDC2009Notes.aspx">original
post</a> for some conventions I tried to use.</em>
        </p>
        <p>
PDC Link: <a href="http://microsoftpdc.com/Sessions/CL22">Advanced Topics for Building
Large-Scale Applications with Microsoft Silverlight</a><br />
Presenter: <a href="http://www.johnpapa.net">John Papa</a> (@john_papa)
</p>
        <p>
The title of this presentation is a little misleading. It could have just as easily
been titled, best practices for building line of business applications in SilverLight.
The concepts, if not most of the code can be applied to WPF as well. There was a lot
of talk about <a href="http://www.codeplex.com/CompositeWPF">Prism</a>, which I have
not looked at in great detail. However, as a result of this presentation, I will take
a closer look at it once I get around to working with SilverLight and WPF more. John
pointed out several times that you are able to pick and choose what parts of Prism
you want to use, which at least makes it sound a little less invasive then some of
the other things to come out of Patterns and Practice. 
</p>
        <p>
A similar framework which is not developed by Microsoft is <a href="http://www.codeplex.com/caliburn">Caliburn</a>.
Which one is better, is probably open to debate, and both are continued to be developed.
John did mention some gaps in Prism, which he developed some code for (posted via
his blog), but perhaps these are available in Caliburn. If you are just starting out
with SilverLight or WPF, I would suggest looking at both frameworks. If you are already
using one or the other, I don’t know how much sense it would make to switch, but I
always like to keep my options open. 
</p>
        <p>
          <strong>MVVM</strong>
        </p>
        <p>
The first part of the presentation was focused on defining MVVM, or the Model, View,
View-Model pattern. The primary benefit of the MVVM pattern, is that is allows for
good separation of concerns, which leads to increased testability and maintainability.
As you can see below, a lot of time was spent on describing the View-Model and how
it fits in, while the View and Model are fairly straight forward.
</p>
        <ul>
          <li>
View: Responsible for rendering the UI only 
</li>
          <li>
Model: Contains your domain entities (i.e. customer, order and order details) 
</li>
          <li>
View-Model: 
<ul><li>
Handles the communication between your View and Model thru bindings, commands, events. 
</li><li>
Responsible for providing everything (data) a particular view requires. 
</li><li>
Sometimes your View-Model will look almost identical to your model. Other times, it
will contain a mash-up of various entities as required by the view. 
</li><li><em>Ensures that your view knows nothing about your model, and that your model doesn’t
known anything about the view (or require references to view related dependencies)</em></li></ul></li>
        </ul>
        <p>
Three ways to implement MVVM were presented. I had never considered the first two,
while the 3rd one is where frameworks like Prism, Caliburn, Ninject (Inversion of
control) come into play.
</p>
        <ul>
          <li>
ViewFirst (Static Resource): View Model can be created as a static resource in the
view. This tightly couples the View Model to the view, but gives you the best experience
when using Blend (referred to as blenability) 
</li>
          <li>
ViewFirst (Code Behind): The view is injected to the View Model constructor. Since
you loose the blendability, I’m not sure why you would pick this over option 3. 
</li>
          <li>
View + View Model Marrige: Use a intermediary to marry the View and the View-Model
together. Again, you loose blendability, but this is the approach that everyone takes
when using Prism, Caliburn or a home grown framework. 
</li>
        </ul>
        <p>
When creating a SilverLight application using MVVM, there are some common functionality
that you need to implement, which is where Prism and Caliburn come into play. Since
this session used Prism, I will list what was shown, which was limited to what Prism
can offer. I expect that Caliburn offers a similar set of functionality. 
</p>
        <ul>
          <li>
Shell: Container for all UI modules, such as menus, windows etc. 
</li>
          <li>
Regions: Shell is made up of regions which control where UI modules are displayed. 
</li>
          <li>
Modules: Separate code modules that can be developed in isolation and then loaded
by Prism. Modules can talk to one another thru event aggregation (<em>I wonder if
MEF would be a better choice</em>)</li>
          <li>
Event Aggregation: An eventing model that allows for cross module communication.</li>
          <li>
            <strike>Commands:</strike> SilverLight 4 adds support for commands, so it is my understanding
you do not need to use Prism’s command support anymore.</li>
          <li>
Bootstrapper: Controls application startup and configuration. Configure your IoC here. 
</li>
          <li>
Delegate Command object for use with commands (very simple class to create if you
are not using Prism)</li>
        </ul>
        <p>
Commands:
</p>
        <ul>
          <li>
Invoke an event on your view and have your view model respond to it. 
</li>
          <li>
When you invoke a command, you expect a response. 
</li>
          <li>
Commands work out of the box well with buttons. However you need to create new command
objects that implement ICommand for use with other controls. John puts these objects
in his Infrastructure dll, and I think he may have provided some of this code on his
blog. 
</li>
          <li>
            <em>I still have a lot to learn on commanding</em>
          </li>
        </ul>
        <img width="0" height="0" src="http://blog.salvoz.com/aggbug.ashx?id=5910971b-e00d-46cb-b433-d1239489d651" />
        <br />
        <hr />
This weblog is sponsored by <a href="http://www.salvoz.com">Adam Salvo</a>. 
</body>
      <title>PDC09 – CL22: Advanced Topics for Building Large-Scale Applications with Microsoft Silverlight</title>
      <guid isPermaLink="false">http://blog.salvoz.com/PermaLink,guid,5910971b-e00d-46cb-b433-d1239489d651.aspx</guid>
      <link>http://blog.salvoz.com/2009/11/29/PDC09CL22AdvancedTopicsForBuildingLargeScaleApplicationsWithMicrosoftSilverlight.aspx</link>
      <pubDate>Sun, 29 Nov 2009 03:45:42 GMT</pubDate>
      <description>&lt;p&gt;
&lt;em&gt;This post is part of my PDC09 Conference Notes series. These are my raw notes
taken while watching the various session videos from PDC09. Refer to my &lt;a href="http://blog.salvoz.com/2009/11/25/PDC2009Notes.aspx"&gt;original
post&lt;/a&gt; for some conventions I tried to use.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
PDC Link: &lt;a href="http://microsoftpdc.com/Sessions/CL22"&gt;Advanced Topics for Building
Large-Scale Applications with Microsoft Silverlight&lt;/a&gt;
&lt;br&gt;
Presenter: &lt;a href="http://www.johnpapa.net"&gt;John Papa&lt;/a&gt; (@john_papa)
&lt;/p&gt;
&lt;p&gt;
The title of this presentation is a little misleading. It could have just as easily
been titled, best practices for building line of business applications in SilverLight.
The concepts, if not most of the code can be applied to WPF as well. There was a lot
of talk about &lt;a href="http://www.codeplex.com/CompositeWPF"&gt;Prism&lt;/a&gt;, which I have
not looked at in great detail. However, as a result of this presentation, I will take
a closer look at it once I get around to working with SilverLight and WPF more. John
pointed out several times that you are able to pick and choose what parts of Prism
you want to use, which at least makes it sound a little less invasive then some of
the other things to come out of Patterns and Practice. 
&lt;/p&gt;
&lt;p&gt;
A similar framework which is not developed by Microsoft is &lt;a href="http://www.codeplex.com/caliburn"&gt;Caliburn&lt;/a&gt;.
Which one is better, is probably open to debate, and both are continued to be developed.
John did mention some gaps in Prism, which he developed some code for (posted via
his blog), but perhaps these are available in Caliburn. If you are just starting out
with SilverLight or WPF, I would suggest looking at both frameworks. If you are already
using one or the other, I don’t know how much sense it would make to switch, but I
always like to keep my options open. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;MVVM&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The first part of the presentation was focused on defining MVVM, or the Model, View,
View-Model pattern. The primary benefit of the MVVM pattern, is that is allows for
good separation of concerns, which leads to increased testability and maintainability.
As you can see below, a lot of time was spent on describing the View-Model and how
it fits in, while the View and Model are fairly straight forward.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
View: Responsible for rendering the UI only 
&lt;li&gt;
Model: Contains your domain entities (i.e. customer, order and order details) 
&lt;li&gt;
View-Model: 
&lt;ul&gt;
&lt;li&gt;
Handles the communication between your View and Model thru bindings, commands, events. 
&lt;li&gt;
Responsible for providing everything (data) a particular view requires. 
&lt;li&gt;
Sometimes your View-Model will look almost identical to your model. Other times, it
will contain a mash-up of various entities as required by the view. 
&lt;li&gt;
&lt;em&gt;Ensures that your view knows nothing about your model, and that your model doesn’t
known anything about the view (or require references to view related dependencies)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Three ways to implement MVVM were presented. I had never considered the first two,
while the 3rd one is where frameworks like Prism, Caliburn, Ninject (Inversion of
control) come into play.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
ViewFirst (Static Resource): View Model can be created as a static resource in the
view. This tightly couples the View Model to the view, but gives you the best experience
when using Blend (referred to as blenability) 
&lt;li&gt;
ViewFirst (Code Behind): The view is injected to the View Model constructor. Since
you loose the blendability, I’m not sure why you would pick this over option 3. 
&lt;li&gt;
View + View Model Marrige: Use a intermediary to marry the View and the View-Model
together. Again, you loose blendability, but this is the approach that everyone takes
when using Prism, Caliburn or a home grown framework. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
When creating a SilverLight application using MVVM, there are some common functionality
that you need to implement, which is where Prism and Caliburn come into play. Since
this session used Prism, I will list what was shown, which was limited to what Prism
can offer. I expect that Caliburn offers a similar set of functionality. 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Shell: Container for all UI modules, such as menus, windows etc. 
&lt;/li&gt;
&lt;li&gt;
Regions: Shell is made up of regions which control where UI modules are displayed. 
&lt;/li&gt;
&lt;li&gt;
Modules: Separate code modules that can be developed in isolation and then loaded
by Prism. Modules can talk to one another thru event aggregation (&lt;em&gt;I wonder if
MEF would be a better choice&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;
Event Aggregation: An eventing model that allows for cross module communication.&lt;/li&gt;
&lt;li&gt;
&lt;strike&gt;Commands:&lt;/strike&gt; SilverLight 4 adds support for commands, so it is my understanding
you do not need to use Prism’s command support anymore.&lt;/li&gt;
&lt;li&gt;
Bootstrapper: Controls application startup and configuration. Configure your IoC here. 
&lt;/li&gt;
&lt;li&gt;
Delegate Command object for use with commands (very simple class to create if you
are not using Prism)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Commands:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Invoke an event on your view and have your view model respond to it. 
&lt;/li&gt;
&lt;li&gt;
When you invoke a command, you expect a response. 
&lt;/li&gt;
&lt;li&gt;
Commands work out of the box well with buttons. However you need to create new command
objects that implement ICommand for use with other controls. John puts these objects
in his Infrastructure dll, and I think he may have provided some of this code on his
blog. 
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;I still have a lot to learn on commanding&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://blog.salvoz.com/aggbug.ashx?id=5910971b-e00d-46cb-b433-d1239489d651" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
This weblog is sponsored by &lt;a href="http://www.salvoz.com"&gt;Adam Salvo&lt;/a&gt;. </description>
      <comments>http://blog.salvoz.com/CommentView,guid,5910971b-e00d-46cb-b433-d1239489d651.aspx</comments>
      <category>Technology/Conference Notes</category>
      <category>Technology/Silverlight</category>
      <category>Technology/WPF</category>
    </item>
    <item>
      <trackback:ping>http://blog.salvoz.com/Trackback.aspx?guid=636a3f84-f76c-4381-a051-3b1140b07066</trackback:ping>
      <pingback:server>http://blog.salvoz.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.salvoz.com/PermaLink,guid,636a3f84-f76c-4381-a051-3b1140b07066.aspx</pingback:target>
      <dc:creator>Adam Salvo</dc:creator>
      <wfw:comment>http://blog.salvoz.com/CommentView,guid,636a3f84-f76c-4381-a051-3b1140b07066.aspx</wfw:comment>
      <wfw:commentRss>http://blog.salvoz.com/SyndicationService.asmx/GetEntryCommentsRss?guid=636a3f84-f76c-4381-a051-3b1140b07066</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Well it’s not exactly my first, but might as well be. Aside from playing around with
WPF a couple of times, I’ve never really sat down and written an application from
start to finish. Hopefully, this will be one time where I do finish.
</p>
        <p>
Given a set of requirements that contains a series of screens, I am to implement a
wizard like interface. Since this application is targeting external customers, looks
will count for something. I also want to make sure that there is no confusion between
the old application and this new version of the application.
</p>
        <p>
To start with, I have installed Expression Studio 3, along with the WPF themes from
the WPF toolkit. The themes are part of the <a href="http://wpf.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=14962">WPF
futures</a> release in the WPF toolkit project on CodePlex. I then created a new WPF
application in Visual Studio (since I was waiting for Expression to download and install)
and added the Expression dark theme to my App.Xaml file as a resource dictionary (key
section is in bold below). You can see in the source attribute, that I have added
themes folder that will contain all of the downloaded themes. I then switched to Expression
Blend 3 to begin work on the UI in earnest. 
</p>
        <pre>&lt;Application x:Class="ThemesSample.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml"&gt;
   <strong> &lt;Application.Resources&gt;
&lt;ResourceDictionary Source="Themes\ExpressionDark.xaml"/&gt; &lt;/Application.Resources&gt;</strong> &lt;/Application&gt; </pre>
        <p>
As I am a firm believer in not re-inventing a wheel, a quick Bing search gave me some
possible WPF wizard implementations. There were a couple of pay options, and one open
source option,  <a href="http://pwlodek.blogspot.com/">Piotr Wlodek’s</a><a href="http://pwlodek.blogspot.com/2009/02/wpf-wizard-control-part-ii.html">WPF
Wizard Control</a>. His sample application and code looked pretty straight forward
and I was fairly certain I could massage it into my application without too many problems.
</p>
        <p>
After downloading and extracting the WPF Wizard Control, I was presented with three
projects. Pitor’s post uses the code in the WPF Wizard 2 project, so I started there
as well. The base control is named Wizard and is in the controls folder. So I created
a controls folder in my project as well, and imported Wizard.cs by using the Add Existing
Item option in Blend and updated the namespace to match my project.
</p>
        <p>
Next I deleted the MainWindow.xaml file that was created with my new project, and
imported the Window1.xaml from the WPF Wizard 2 project. Again, I had to go thru and
update the namespace in the code behind file, as well as change the class name in
Window1.xaml from WpfWizard to MyNamingConvention.Window1. You will also need to update
the reference to Controls on line 4 in Window1.xaml to match your namespace. Once
finished, you should be able to build, and see an empty white window in the designer
for Window1.
</p>
        <p>
So where is the Wizard? Well, the original project uses a Generic.Xaml file to define
the styles of the various UI elements. Since we haven't imported that yet, we don’t
see anything. The problem that we need to solve is “merging” the Generic.xaml from
the Wpf Wizard project with our themes that we downloaded. I wanted to show you what
the application looked like at this point, because I think it shows how WPF operates
differently from other types of applications.
</p>
        <p>
In order to have a good starting point, I went ahead and imported the Generic.xaml
file from the Wpf Wizard project, and updated the namespace on line 3. After rebuilding,
I now start to see some actual UI elements on Window1. You should also note that the
check box on the side bar is in fact picking up our ExpressionDark theme. However,
the buttons are not picking up the theme, and the background is certainly not appropriate
for our ExpressDark theme. 
</p>
        <p>
To fix the buttons, I went ahead and removed the style property for each button in
Generic.xml, and manually set the margins and width on each button. This allows the
buttons to pick up the style from ExpressionDark. There is a way to do some style
inheritance, but at this point I don’t think I need it for the buttons. However, you
can add the following attribute to the a style tag: BasedOn="{StaticResource {x:Type
Button}}” – See this <a href="http://www.switchonthecode.com/tutorials/wpf-the-basedon-style-property">post</a> for
more information on the BasedOn attribute. 
</p>
        <p>
The background color for the wizard was really giving me problems, so I decided to
skip it for now and add the rest of the my wizard pages so I could test that out.
Switching back to Window1.xaml (view XAML), you will see that the wizard is made up
of a Wizard control tag, and then 1 or more WizardPage child controls (see image below).
The hierarchy is:
</p>
        <ul>
          <li>
Wizard 
<ul><li>
WizardPage (CanFinish, CanCancel) 
<ul><li>
SideHeader: Option. I’m using it to show progress thru the Wizard 
</li><li>
Border: Main content and additional controls go here</li></ul></li></ul></li>
        </ul>
        <p>
          <a href="http://blog.salvoz.com/content/binary/WindowsLiveWriter/MyFirstWPFApplication_9543/image_2.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog.salvoz.com/content/binary/WindowsLiveWriter/MyFirstWPFApplication_9543/image_thumb.png" width="644" height="212" />
          </a>
        </p>
        <p>
I created my first page, complete with a stack panel in the SideHeader, which contains
6 labels to indicate which step of the Wizard we are on. I then copied and pasted
the &lt;WizardPage&gt; 5 times, changed the comment before each page, and updated
the label names to get my basic 6 screen wizard. The CanCancel attribute on the Wizard
page is set to true by default, so I left that as is, and since I only want someone
to be able to finish after getting to the last screen, I set CanFinish to true on
the 6th &lt;WizardPage&gt;. 
</p>
        <p>
I went back to the background color and finally figured out that you need to change
the styles defined in Window1.xaml, not Generic.xaml for:
</p>
        <ul>
          <li>
x:Key="{x:Static Controls:Wizard.HeaderPanelBorderResourceKey}"</li>
          <li>
x:Key="{x:Static Controls:Wizard.SideHeaderPanelBorderResourceKey}"</li>
          <li>
x:Key="{x:Static Controls:Wizard.NavigationPanelBorderResourceKey}"</li>
          <li>
x:Key="{x:Static Controls:Wizard.ContentPanelBorderResourceKey}"</li>
        </ul>
        <p>
I’m going to assume that since the styles were defined in two locations, the one in
Window1.xaml takes precedence. The styles in Generic.xaml are either there as defaults,
or were unintentionally left there by the original author. 
</p>
        <p>
My final touch, was to define a second style for my ProgressLabels, called ProgressLabelSelected,
which changes the foreground color. When not selected the label is black, when selected
the label is white. Here is what Window1.xaml now looks for me after the background
and label changes, and I think it’s coming along nicely.
</p>
        <p>
          <a href="http://blog.salvoz.com/content/binary/WindowsLiveWriter/MyFirstWPFApplication_9543/image_6.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.salvoz.com/content/binary/WindowsLiveWriter/MyFirstWPFApplication_9543/image_thumb_2.png" width="644" height="481" />
          </a>
        </p>
        <p>
        </p>
        <p>
One thing that I do not like about this wizard control, but is present in almost any
wizard control I have used, is that it’s difficult to work with the various wizard
screens. While you can edit the xaml directly, that is kind of a pain and gives no
design time view. Hiding the WizardPage doesn’t work, and so far my only option is
to drag the wizard page I want to work with to the top of the list. 
</p>
        <p>
I think I’m at a good spot to leave off at for this post as I move onto adding more
controls and content to the various Wizard Pages. I’ll come back with a second post
on what I learn during that process.
</p>
        <img width="0" height="0" src="http://blog.salvoz.com/aggbug.ashx?id=636a3f84-f76c-4381-a051-3b1140b07066" />
        <br />
        <hr />
This weblog is sponsored by <a href="http://www.salvoz.com">Adam Salvo</a>. 
</body>
      <title>My First WPF Application</title>
      <guid isPermaLink="false">http://blog.salvoz.com/PermaLink,guid,636a3f84-f76c-4381-a051-3b1140b07066.aspx</guid>
      <link>http://blog.salvoz.com/2009/11/26/MyFirstWPFApplication.aspx</link>
      <pubDate>Thu, 26 Nov 2009 11:51:00 GMT</pubDate>
      <description>&lt;p&gt;
Well it’s not exactly my first, but might as well be. Aside from playing around with
WPF a couple of times, I’ve never really sat down and written an application from
start to finish. Hopefully, this will be one time where I do finish.
&lt;/p&gt;
&lt;p&gt;
Given a set of requirements that contains a series of screens, I am to implement a
wizard like interface. Since this application is targeting external customers, looks
will count for something. I also want to make sure that there is no confusion between
the old application and this new version of the application.
&lt;/p&gt;
&lt;p&gt;
To start with, I have installed Expression Studio 3, along with the WPF themes from
the WPF toolkit. The themes are part of the &lt;a href="http://wpf.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=14962"&gt;WPF
futures&lt;/a&gt; release in the WPF toolkit project on CodePlex. I then created a new WPF
application in Visual Studio (since I was waiting for Expression to download and install)
and added the Expression dark theme to my App.Xaml file as a resource dictionary (key
section is in bold below). You can see in the source attribute, that I have added
themes folder that will contain all of the downloaded themes. I then switched to Expression
Blend 3 to begin work on the UI in earnest. 
&lt;/p&gt;
&lt;pre&gt;&amp;lt;Application x:Class="ThemesSample.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml"&amp;gt;
   &lt;strong&gt; &amp;lt;Application.Resources&amp;gt;
&amp;lt;ResourceDictionary Source="Themes\ExpressionDark.xaml"/&amp;gt; &amp;lt;/Application.Resources&amp;gt;&lt;/strong&gt; &amp;lt;/Application&amp;gt; &lt;/pre&gt;
&lt;p&gt;
As I am a firm believer in not re-inventing a wheel, a quick Bing search gave me some
possible WPF wizard implementations. There were a couple of pay options, and one open
source option,&amp;nbsp; &lt;a href="http://pwlodek.blogspot.com/"&gt;Piotr Wlodek’s&lt;/a&gt; &lt;a href="http://pwlodek.blogspot.com/2009/02/wpf-wizard-control-part-ii.html"&gt;WPF
Wizard Control&lt;/a&gt;. His sample application and code looked pretty straight forward
and I was fairly certain I could massage it into my application without too many problems.
&lt;/p&gt;
&lt;p&gt;
After downloading and extracting the WPF Wizard Control, I was presented with three
projects. Pitor’s post uses the code in the WPF Wizard 2 project, so I started there
as well. The base control is named Wizard and is in the controls folder. So I created
a controls folder in my project as well, and imported Wizard.cs by using the Add Existing
Item option in Blend and updated the namespace to match my project.
&lt;/p&gt;
&lt;p&gt;
Next I deleted the MainWindow.xaml file that was created with my new project, and
imported the Window1.xaml from the WPF Wizard 2 project. Again, I had to go thru and
update the namespace in the code behind file, as well as change the class name in
Window1.xaml from WpfWizard to MyNamingConvention.Window1. You will also need to update
the reference to Controls on line 4 in Window1.xaml to match your namespace. Once
finished, you should be able to build, and see an empty white window in the designer
for Window1.
&lt;/p&gt;
&lt;p&gt;
So where is the Wizard? Well, the original project uses a Generic.Xaml file to define
the styles of the various UI elements. Since we haven't imported that yet, we don’t
see anything. The problem that we need to solve is “merging” the Generic.xaml from
the Wpf Wizard project with our themes that we downloaded. I wanted to show you what
the application looked like at this point, because I think it shows how WPF operates
differently from other types of applications.
&lt;/p&gt;
&lt;p&gt;
In order to have a good starting point, I went ahead and imported the Generic.xaml
file from the Wpf Wizard project, and updated the namespace on line 3. After rebuilding,
I now start to see some actual UI elements on Window1. You should also note that the
check box on the side bar is in fact picking up our ExpressionDark theme. However,
the buttons are not picking up the theme, and the background is certainly not appropriate
for our ExpressDark theme. 
&lt;/p&gt;
&lt;p&gt;
To fix the buttons, I went ahead and removed the style property for each button in
Generic.xml, and manually set the margins and width on each button. This allows the
buttons to pick up the style from ExpressionDark. There is a way to do some style
inheritance, but at this point I don’t think I need it for the buttons. However, you
can add the following attribute to the a style tag: BasedOn="{StaticResource {x:Type
Button}}” – See this &lt;a href="http://www.switchonthecode.com/tutorials/wpf-the-basedon-style-property"&gt;post&lt;/a&gt; for
more information on the BasedOn attribute. 
&lt;/p&gt;
&lt;p&gt;
The background color for the wizard was really giving me problems, so I decided to
skip it for now and add the rest of the my wizard pages so I could test that out.
Switching back to Window1.xaml (view XAML), you will see that the wizard is made up
of a Wizard control tag, and then 1 or more WizardPage child controls (see image below).
The hierarchy is:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Wizard 
&lt;ul&gt;
&lt;li&gt;
WizardPage (CanFinish, CanCancel) 
&lt;ul&gt;
&lt;li&gt;
SideHeader: Option. I’m using it to show progress thru the Wizard 
&lt;li&gt;
Border: Main content and additional controls go here&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;a href="http://blog.salvoz.com/content/binary/WindowsLiveWriter/MyFirstWPFApplication_9543/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog.salvoz.com/content/binary/WindowsLiveWriter/MyFirstWPFApplication_9543/image_thumb.png" width="644" height="212"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
I created my first page, complete with a stack panel in the SideHeader, which contains
6 labels to indicate which step of the Wizard we are on. I then copied and pasted
the &amp;lt;WizardPage&amp;gt; 5 times, changed the comment before each page, and updated
the label names to get my basic 6 screen wizard. The CanCancel attribute on the Wizard
page is set to true by default, so I left that as is, and since I only want someone
to be able to finish after getting to the last screen, I set CanFinish to true on
the 6th &amp;lt;WizardPage&amp;gt;. 
&lt;/p&gt;
&lt;p&gt;
I went back to the background color and finally figured out that you need to change
the styles defined in Window1.xaml, not Generic.xaml for:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
x:Key="{x:Static Controls:Wizard.HeaderPanelBorderResourceKey}"&lt;/li&gt;
&lt;li&gt;
x:Key="{x:Static Controls:Wizard.SideHeaderPanelBorderResourceKey}"&lt;/li&gt;
&lt;li&gt;
x:Key="{x:Static Controls:Wizard.NavigationPanelBorderResourceKey}"&lt;/li&gt;
&lt;li&gt;
x:Key="{x:Static Controls:Wizard.ContentPanelBorderResourceKey}"&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I’m going to assume that since the styles were defined in two locations, the one in
Window1.xaml takes precedence. The styles in Generic.xaml are either there as defaults,
or were unintentionally left there by the original author. 
&lt;/p&gt;
&lt;p&gt;
My final touch, was to define a second style for my ProgressLabels, called ProgressLabelSelected,
which changes the foreground color. When not selected the label is black, when selected
the label is white. Here is what Window1.xaml now looks for me after the background
and label changes, and I think it’s coming along nicely.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.salvoz.com/content/binary/WindowsLiveWriter/MyFirstWPFApplication_9543/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.salvoz.com/content/binary/WindowsLiveWriter/MyFirstWPFApplication_9543/image_thumb_2.png" width="644" height="481"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
One thing that I do not like about this wizard control, but is present in almost any
wizard control I have used, is that it’s difficult to work with the various wizard
screens. While you can edit the xaml directly, that is kind of a pain and gives no
design time view. Hiding the WizardPage doesn’t work, and so far my only option is
to drag the wizard page I want to work with to the top of the list. 
&lt;/p&gt;
&lt;p&gt;
I think I’m at a good spot to leave off at for this post as I move onto adding more
controls and content to the various Wizard Pages. I’ll come back with a second post
on what I learn during that process.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.salvoz.com/aggbug.ashx?id=636a3f84-f76c-4381-a051-3b1140b07066" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
This weblog is sponsored by &lt;a href="http://www.salvoz.com"&gt;Adam Salvo&lt;/a&gt;. </description>
      <comments>http://blog.salvoz.com/CommentView,guid,636a3f84-f76c-4381-a051-3b1140b07066.aspx</comments>
      <category>Technology/WPF</category>
    </item>
  </channel>
</rss>