<?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>CTRLALT313373.com - Development</title>
    <link>http://weblog.ctrlalt313373.com/</link>
    <description>.Net Wanderings</description>
    <language>en-us</language>
    <copyright>David A. Osborn</copyright>
    <lastBuildDate>Fri, 13 Feb 2009 02:20:29 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>davido@ctrlalt313373.com</managingEditor>
    <webMaster>davido@ctrlalt313373.com</webMaster>
    <item>
      <trackback:ping>http://weblog.ctrlalt313373.com/Trackback.aspx?guid=2943bbeb-dd0c-440c-846b-15ffcbd46206</trackback:ping>
      <pingback:server>http://weblog.ctrlalt313373.com/pingback.aspx</pingback:server>
      <pingback:target>http://weblog.ctrlalt313373.com/PermaLink,guid,2943bbeb-dd0c-440c-846b-15ffcbd46206.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://weblog.ctrlalt313373.com/CommentView,guid,2943bbeb-dd0c-440c-846b-15ffcbd46206.aspx</wfw:comment>
      <wfw:commentRss>http://weblog.ctrlalt313373.com/SyndicationService.asmx/GetEntryCommentsRss?guid=2943bbeb-dd0c-440c-846b-15ffcbd46206</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Well after a bit of work and some help from this blog <a href="http://www.grumpydev.com/2008/12/26/surface-sdk-on-vista-x64/">post</a>,
I was able to get the Microsoft Surface SDK working on my 64bit Vista machine. The
documentation for the SDK says that it needs to run on 32bit Vista but Steven Robbins
seems to have figured out the steps to get around that. Now that I have it up and
running I hope to put up a few blog posts on doing Surface development and hopefully
I won't run into any issues using 64bit. If anyone would like to donate me the money
to buy an actual Surface unit I would be grateful, but until then the Surface simulator
appears to be a decent environment that allows you to hook up multiple mice to act
as different finger touches. The below sample application comes with the sdk and allows
you to select a picture to create a puzzle out of and then put the puzzle together.
I can't wait to get my hands dirty and create a Surface application of my own. 
</p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/021309_0219_SurfaceSDK1.png" alt="" />
        </p>
        <img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=2943bbeb-dd0c-440c-846b-15ffcbd46206" />
      </body>
      <title>Surface SDK</title>
      <guid isPermaLink="false">http://weblog.ctrlalt313373.com/PermaLink,guid,2943bbeb-dd0c-440c-846b-15ffcbd46206.aspx</guid>
      <link>http://weblog.ctrlalt313373.com/2009/02/13/SurfaceSDK.aspx</link>
      <pubDate>Fri, 13 Feb 2009 02:20:29 GMT</pubDate>
      <description>&lt;p&gt;
Well after a bit of work and some help from this blog &lt;a href="http://www.grumpydev.com/2008/12/26/surface-sdk-on-vista-x64/"&gt;post&lt;/a&gt;,
I was able to get the Microsoft Surface SDK working on my 64bit Vista machine. The
documentation for the SDK says that it needs to run on 32bit Vista but Steven Robbins
seems to have figured out the steps to get around that. Now that I have it up and
running I hope to put up a few blog posts on doing Surface development and hopefully
I won't run into any issues using 64bit. If anyone would like to donate me the money
to buy an actual Surface unit I would be grateful, but until then the Surface simulator
appears to be a decent environment that allows you to hook up multiple mice to act
as different finger touches. The below sample application comes with the sdk and allows
you to select a picture to create a puzzle out of and then put the puzzle together.
I can't wait to get my hands dirty and create a Surface application of my own. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/021309_0219_SurfaceSDK1.png" alt="" /&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=2943bbeb-dd0c-440c-846b-15ffcbd46206" /&gt;</description>
      <comments>http://weblog.ctrlalt313373.com/CommentView,guid,2943bbeb-dd0c-440c-846b-15ffcbd46206.aspx</comments>
      <category>Development</category>
      <category>Microsoft Surface</category>
    </item>
    <item>
      <trackback:ping>http://weblog.ctrlalt313373.com/Trackback.aspx?guid=2da2f1cf-b0be-487d-b5b4-4df5aa379407</trackback:ping>
      <pingback:server>http://weblog.ctrlalt313373.com/pingback.aspx</pingback:server>
      <pingback:target>http://weblog.ctrlalt313373.com/PermaLink,guid,2da2f1cf-b0be-487d-b5b4-4df5aa379407.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://weblog.ctrlalt313373.com/CommentView,guid,2da2f1cf-b0be-487d-b5b4-4df5aa379407.aspx</wfw:comment>
      <wfw:commentRss>http://weblog.ctrlalt313373.com/SyndicationService.asmx/GetEntryCommentsRss?guid=2da2f1cf-b0be-487d-b5b4-4df5aa379407</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
With the release of Silverlight 2.0 also came the functionality of Deep Zoom. Deep
Zoom optimizes the viewing of large images in a smooth manner by partitioning an image
into tiles and levels of resolution of the original image. Using this method allows
for the browser to download a lower resolution image for a faster download speed and
then only grab the higher resolution image if the user zooms in. When the user does
zoom in the tile that represents that section of the higher resolution image is download
to the browser again saving the viewer download time and enhancing the user experience. 
</p>
        <p>
In order to begin working with Deep Zoom the first thing we need to do is prepare
an image for Deep Zoom by creating tiles out of the image of different resolutions.
This would be a bit cumbersome to do by hand so luckily Microsoft has provided us
with the Deep Zoom Composer which you can <a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=1&amp;url=http%3A%2F%2Fwww.microsoft.com%2Fdownloads%2Fdetails.aspx%3Ffamilyid%3D457b17b7-52bf-4bda-87a3-fa8a4673f8bf&amp;ei=igM8SbX_MojaM8-R2a8F&amp;usg=AFQjCNE5i8Ndl2AZGRxmQ8seQB1MZawSVA&amp;sig2=3w05HjQyqEhCJaSEFkrewA">download</a> for
free. This allows us to create the Deep Zoom images and even allows us to create a
collage of image in Deep Zoom. We will be doing the latter, using the numerous amount
of photos that I took while traveling through Europe for the month of September. 
</p>
        <p>
The first thing we need to do is create a new project in Deep Zoom Composer. Do this
by running the Deep Zoom Composer and selecting new project. After doing this you
will see three tabs along the top – Import, Compose, and Export. If you are not already
on the Import tab, select it, and then we need to add the images that we want to work
with. In my case I will be adding in all my pictures from Rome. Click the Add Image…
button on the right and select the images that you want to add. Remember that you
can select multiple images at once to get your images imported in faster. 
</p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa1.png" alt="" />
        </p>
        <p>
        </p>
        <p>
Once the images are imported we then switch over to the Compose tab. The tab allows
you to create how the final image will look in your Silverlight Application. Select
your imported images from the side and place them on the canvas how you would like
them to appear. You can zoom in and out on the canvas and place your photos at different
depths, even embedding them within each other. For instance I have an image of the
Coliseum from the distance with a sign that is on the side of it. I then have a closer
image of that sign as another picture. The Deep Zoom composer allows me to embed the
more detailed image of the sign into the image of the Coliseum. 
</p>
        <p>
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa2.png" alt="" />
        </p>
        <p>
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa3.png" alt="" />
        </p>
        <p>
        </p>
        <p>
In the composer you also have the ability to associate tags with the images. I have
associated various tags with all my images. Through the composer you can only apply
one string as a tag, so I have used this field to enter multiple "tags" separated
by commas. In a future tutorial I will demonstrate how to create a tag filter to filter
down images shown in the MultiScaleImage. 
</p>
        <p>
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa4.png" alt="" />
        </p>
        <p>
        </p>
        <p>
Once we have exported the images from Deep Zoom Composer it is now time to get our
hands dirty in Visual Studio 2008. In order to work with Silverlight 2.0 applications
you are going to need 3 things, Visual Studio 2008 SP1, the Silverlight SDK, and the
Silverlight tools for Visual Studio 2008. Fire up vs2008, go to File-&gt;New-&gt;Project
and under Visual C# (or if you prefer you can select VB) select Silverlight. Then
select Silverlight Application on the right, name your solution, and select where
you want to save it. 
</p>
        <p>
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa5.png" alt="" />
        </p>
        <p>
        </p>
        <p>
Next a window will appear that will ask you if you want to add a new ASP.NET web project
to the solution or generate a test page at build time. Every Silverlight application
needs to be hosted inside a web application so we will let Visual Studio add a project
to our solution for this purpose. 
</p>
        <p>
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa6.png" alt="" />
        </p>
        <p>
        </p>
        <p>
If you now look in the Solution Explorer you will see that we have an empty Silverlight
Application called DeepZoomExample2 and a ASP.NET web project called DeepZoomExample2.Web.
The web project has two pages that were created for us, an aspx page and a html page
that hosts our Silverlight Application. 
</p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa7.png" alt="" />
        </p>
        <p>
        </p>
        <p>
Next we need to add our exported images to the web project. Add a new folder under
the ClientBin folder on the Web Project and call it GeneratedImages. The ClientBin
folder is where the compiled .xap file from your Silverlight will live so this is
the easiest place to put our exported files. Now go into your exported folder from
the Deep Zoom Composer and open up the generated images folder and copy the dzc_output_files
folder, and the dzc_output_images folder along with the three files, dzc_output.xml,
Metadata.xml, SparseImageSceneGraph.xml into the new GeneratedImages folder that you
created in your web project. If you used a lot of images this may take some time to
copy. Your Solution Explorer should now look like the following image. 
</p>
        <p>
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa8.png" alt="" />
        </p>
        <p>
        </p>
        <p>
Now it's time to start writing some code. First we add a MultiScaleImage to the Page.xaml
file. The Source property will be directed at the dzc_output.zml files that we copied
into our GeneratedImages folder. 
</p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">&lt;</span>
            <span style="color:#a31515">Grid</span>
            <span style="color:blue">
            </span>
            <span style="color:red">x:Name</span>
            <span style="color:blue">=</span>"<span style="color:blue">LayoutRoot</span>"<span style="color:blue"></span><span style="color:red">Background</span><span style="color:blue">=</span>"<span style="color:blue">White</span>"<span style="color:blue">&gt; </span></span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue"> &lt;</span>
            <span style="color:#a31515">MultiScaleImage</span>
            <span style="color:blue">
            </span>
            <span style="color:red">x:Name</span>
            <span style="color:blue">=</span>"<span style="color:blue">msi</span>"<span style="color:blue"></span><span style="color:red">ViewportWidth</span><span style="color:blue">=</span>"<span style="color:blue">1.0</span>"<span style="color:blue"></span><span style="color:red">Source</span><span style="color:blue">=</span>"<span style="color:blue">/GeneratedImages/dzc_output.xml</span>"<span style="color:blue"> /&gt; </span></span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">&lt;/</span>
            <span style="color:#a31515">Grid</span>
            <span style="color:blue">&gt; </span>
          </span>
        </p>
        <p>
        </p>
        <p>
This is all we need to do to get the basic images on the screen, but that isn't very
exciting so lets wire up some zooming using the mouse button. In the Page.xaml.cs
file we need to add a few variables to store some information: 
</p>
        <p>
        </p>
        <p>
          <span style="color:green; font-family:Courier New; font-size:10pt">//This variable
is used to know if the user has just click the left button or has clicked and dragged </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:blue">bool</span> mouseIsDragging
= <span style="color:blue">false</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Indicates
if left mouse button is down </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:blue">bool</span> mouseButtonPressed
= <span style="color:blue">false</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Starting
Point of the Drag </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:#2b91af">Point</span> dragOffset; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Get
Current ViewPort position of MSI </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:#2b91af">Point</span> currentPosition; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Last
Position of Mouse </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:#2b91af">Point</span> lastMousePos
= <span style="color:blue">new</span><span style="color:#2b91af">Point</span>(); </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">double</span> ZoomFactor </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">get</span>; <span style="color:blue">set</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
We then have three mouse events that we need to handle, LeftMouseButton down, LeftMouseButton
up, and Mouse Move. Then we need to handle the actual zoom. 
</p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green"> Handles
Left Mouse button down event </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;/summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="sender"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="e"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:blue">void</span> LeftMouseButtonDownHandler(<span style="color:blue">object</span> sender, <span style="color:#2b91af">MouseEventArgs</span> e) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Indicate
that the button is down </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> mouseButtonPressed = <span style="color:blue">true</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Reset
Dragging </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> mouseIsDragging = <span style="color:blue">false</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Set
Starting point of the drag if the user start dragging </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> dragOffset = e.GetPosition(<span style="color:blue">this</span>); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> currentPosition = msi.ViewportOrigin; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
In the left mouse button down even, we first set the indicator that the button is
pressed. We then reset the dragging indicator, get the current position of the mouse,
and finally get the current position of the MultiScaleImage. 
</p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green"> Handles
Left Mouse button up event </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;/summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="sender"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="e"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:blue">void</span> LeftMouseButtonUpHandler(<span style="color:blue">object</span> sender, <span style="color:#2b91af">MouseEventArgs</span> e) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Change
flag to mouse button no longer pressed </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> mouseButtonPressed = <span style="color:blue">false</span>; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//If
the user wasn't dragging then we do zooming </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span>(!mouseIsDragging) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Check
if shift was pressed. If so we zoom out, otherwise we zoom in </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">bool</span> shiftDown
= (<span style="color:#2b91af">Keyboard</span>.Modifiers &amp; <span style="color:#2b91af">ModifierKeys</span>.Shift)
== <span style="color:#2b91af">ModifierKeys</span>.Shift; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> ZoomFactor = 2.0; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span> (shiftDown)
ZoomFactor = 0.5; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> Zoom(ZoomFactor, <span style="color:blue">this</span>.lastMousePos); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
When the left mouse button is lifted we change the flag that indicates that the left
mouse button is down and if the user was not dragging. We then check to see if shift
was pressed. If shift was not pressed we zoom in by a factor of 2, but if shift was
pressed we zoom out by a factor of .5. We then call our zoom function (which we have
yet to create) with the zoom factor and the last point the mouse was at. 
</p>
        <p>
        </p>
        <p style="margin-left: 36pt">
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray"> ///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green"> Handlers
the moving of the mouse </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;/summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="sender"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="e"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:blue">void</span> MouseMoveHandler(<span style="color:blue">object</span> sender, <span style="color:#2b91af">MouseEventArgs</span> e) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.lastMousePos
= e.GetPosition(<span style="color:blue">this</span>.msi); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
With the mouse move function all we need to do is capture the position that the mouse
is at. Finally in the below Zoom function that is called from the LeftMouseButtonUpHandler,
we do the actual zooming. 
</p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">void</span> Zoom(<span style="color:blue">double</span> zoom, <span style="color:#2b91af">Point</span> pointToZoom) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:#2b91af">Point</span> logicalPoint
= <span style="color:blue">this</span>.msi.ElementToLogicalPoint(pointToZoom); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.ZoomAboutLogicalPoint(zoom,
logicalPoint.X, logicalPoint.Y); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
As you can see above we have to translate the mouse pointer relative to our MultiScaleImage
and then we use the ZoomAboutLogicalPoint method to handle the zooming for us. The
last thing we need to do is wire up the events to the MultiScaleImage control in the
Page constructor which will look like the following: 
</p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span> Page() </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> InitializeComponent(); </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Wire
up events </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.MouseLeftButtonDown
+= LeftMouseButtonDownHandler; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.MouseLeftButtonUp
+= LeftMouseButtonUpHandler; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.MouseMove
+= MouseMoveHandler; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
If you now run the application you will get the layout of all images on your screen
as seen in the first picture below, and if I click on the picture of St. Peter's Square
in the center of the image the MultiScaleImage control will zoom in on that particular
image as seen in the second picture below. Holding down the shift key while clicking
will zoom the MultiScaleImage back out. 
</p>
        <p>
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa9.png" alt="" />
        </p>
        <p>
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa10.png" alt="" />
        </p>
        <p>
In order to enable panning we need to augment a few functions that we have already
created. Obviously we need to modify the MouseMoveHandler. Initially all this event
was doing was updating the mouse position so that when we zoomed in or out we knew
where the mouse was pointing. Now we are going to have it check to see if the mouse
button is down to indicate that dragging is occurring. Also if the mouse is dragging
we need to update the position so that the MultiScaleImage is centered on to where
the mouse is dragging. Our new MouseMoveHandler appears below. 
</p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green"> Handlers
the moving of the mouse </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;/summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="sender"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="e"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:blue">void</span> MouseMoveHandler(<span style="color:blue">object</span> sender, <span style="color:#2b91af">MouseEventArgs</span> e) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span>(mouseButtonPressed) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> mouseIsDragging = <span style="color:blue">true</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.lastMousePos
= e.GetPosition(<span style="color:blue">this</span>.msi); </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Update
this View of the MultiScaleImage is dragging </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span>(mouseIsDragging) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:#2b91af">Point</span> newOrigin
= <span style="color:blue">new</span><span style="color:#2b91af">Point</span>(); </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> newOrigin.X = currentPosition.X
- </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> (((e.GetPosition(msi).X - dragOffset.X)/msi.ActualWidth)*msi.ViewportWidth); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> newOrigin.Y = currentPosition.Y
- </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> (((e.GetPosition(msi).Y - dragOffset.Y)/msi.ActualWidth)*msi.ViewportWidth); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> msi.ViewportOrigin = newOrigin; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
In our left mouse button down handler we are already handling the dragging functionality
by initializing the mouseIsDragging variable to false, and setting dargOffset to the
initial point that the mouse was at when dragging was started. In the left mouse button
up handler we need to update the dragging indicator that was set to true in the left
mouse button down indicated. The new handler appears below: 
</p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green"> Handles
Left Mouse button up event </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;/summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="sender"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="e"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:blue">void</span> LeftMouseButtonUpHandler(<span style="color:blue">object</span> sender, <span style="color:#2b91af">MouseEventArgs</span> e) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Change
flag to mouse button no longer pressed </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> mouseButtonPressed = <span style="color:blue">false</span>; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//If
the user wasn't dragging then we do zooming </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span>(!mouseIsDragging) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Check
if shift was pressed. If so we zoom out, otherwise we zoom in </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">bool</span> shiftDown
= (<span style="color:#2b91af">Keyboard</span>.Modifiers &amp; <span style="color:#2b91af">ModifierKeys</span>.Shift)
== <span style="color:#2b91af">ModifierKeys</span>.Shift; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> ZoomFactor = 2.0; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span> (shiftDown)
ZoomFactor = 0.5; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> Zoom(ZoomFactor, <span style="color:blue">this</span>.lastMousePos); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> mouseIsDragging = <span style="color:blue">false</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
We now need to add one more handler. If the mouse goes outside the MultiScaleImage
we what to stop the panning so we need to add a Mouse Leave event handler. In the
handler I am also going to reset the mouse down variable when the user leaves the
MultiScaleImage. This way if they leave the image, lift up the mouse button, and re-enter
the image, it won't continue to pan. 
</p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green"> Handles
the mouse leave event </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;/summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="sender"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="e"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:blue">void</span> MouseLeaveHandler(<span style="color:blue">object</span> sender, <span style="color:#2b91af">MouseEventArgs</span> e) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> mouseIsDragging = <span style="color:blue">false</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> mouseButtonPressed = <span style="color:blue">false</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
We now need to assign the event, so in the constructor where we wired up the other
events we need to also wire up the MouseLeave event of the MultiScaleImage: 
</p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span> Page() </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> InitializeComponent(); </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Wire
up events </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.MouseLeftButtonDown
+= LeftMouseButtonDownHandler; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.MouseLeftButtonUp
+= LeftMouseButtonUpHandler; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.MouseMove
+= MouseMoveHandler; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.MouseLeave
+= MouseLeaveHandler; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
There you go. Adding panning was that easy. Now if you fire up the site you can click
and dragging the image around and still zoom in and out using click and shit click. 
</p>
        <p>
The next thing we need to do is add zooming with the scroll wheel. We are going to
do this by using the MouseWheelHelper class provided by <a href="http://blois.us/blog/2008/03/ive-heard-number-of-people-wondering.html">Peter
Blois</a>. So grab this class and add it to your Silverlight Application. With Silverlight
2.0 the silverlight application can reach into the DOM using the Sliverlight DOM bridge
and listen to events in the class, abstracting that away from us. 
</p>
        <p>
The first thing we need to do is create an event to handle the mouse wheel. Inside
this event we set the event to handled so that the system knows that the event has
be taken care of, we set the zoom factor by checking the Delta value that is passed
to us from the MouseWheelHelper class. Finally we call the Zoom method passing the
factor that we want to zoom by and the point we are zooming at, just like if the user
had clicked the mouse button to zoom. 
</p>
        <p>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green"> Handles
the mouse wheel events </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;/summary&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="sender"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:gray">///</span>
            <span style="color:green">
            </span>
            <span style="color:gray">&lt;param
name="e"&gt;&lt;/param&gt; </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:blue">void</span> MouseWheelHandler(<span style="color:blue">object</span> sender, <span style="color:#2b91af">MouseWheelEventArgs</span> e) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Notify
that we handled the event </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> e.Handled = <span style="color:blue">true</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> ZoomFactor = e.Delta &gt; 0
? 1.2 : .80; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> Zoom(ZoomFactor, <span style="color:blue">this</span>.lastMousePos); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
Lastly we wire up with event in our constructor just below where we we wiring up the
rest of the events. The newly modify constructor appears as follows: 
</p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span> Page() </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> InitializeComponent(); </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Wire
up events </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.MouseLeftButtonDown
+= LeftMouseButtonDownHandler; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.MouseLeftButtonUp
+= LeftMouseButtonUpHandler; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.MouseMove
+= MouseMoveHandler; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">this</span>.msi.MouseLeave
+= MouseLeaveHandler; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">new</span>
            <span style="color:#2b91af">MouseWheelHelper</span>(<span style="color:blue">this</span>).Moved
+= MouseWheelHandler; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
If you now build and run the application you'll see that the ability to have zoom
with the scroll wheel of the mouse is now present. Hopefully this has demonstrated
that working with the Deep Zoom functionality and Deem Zoom Composer is fairly simple
and can greatly enhance the user experience for a web site. The even better news is
that Deep Zoom composer will now generate all this functionality for you wrapped into
a Silverlight 2.0 application when you export your Deep Zoom image. This particular
sample was pieced together from what I learned from <a href="http://blog.kirupa.com/">Kirupa
Chinnathambi blog</a> who is currently a member of the Expression Blend team at Microsoft. 
</p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=2da2f1cf-b0be-487d-b5b4-4df5aa379407" />
      </body>
      <title>Deep Zoom Example</title>
      <guid isPermaLink="false">http://weblog.ctrlalt313373.com/PermaLink,guid,2da2f1cf-b0be-487d-b5b4-4df5aa379407.aspx</guid>
      <link>http://weblog.ctrlalt313373.com/2008/12/07/DeepZoomExample.aspx</link>
      <pubDate>Sun, 07 Dec 2008 17:21:38 GMT</pubDate>
      <description>&lt;p&gt;
With the release of Silverlight 2.0 also came the functionality of Deep Zoom. Deep
Zoom optimizes the viewing of large images in a smooth manner by partitioning an image
into tiles and levels of resolution of the original image. Using this method allows
for the browser to download a lower resolution image for a faster download speed and
then only grab the higher resolution image if the user zooms in. When the user does
zoom in the tile that represents that section of the higher resolution image is download
to the browser again saving the viewer download time and enhancing the user experience. 
&lt;/p&gt;
&lt;p&gt;
In order to begin working with Deep Zoom the first thing we need to do is prepare
an image for Deep Zoom by creating tiles out of the image of different resolutions.
This would be a bit cumbersome to do by hand so luckily Microsoft has provided us
with the Deep Zoom Composer which you can &lt;a href="http://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;ct=res&amp;amp;cd=1&amp;amp;url=http%3A%2F%2Fwww.microsoft.com%2Fdownloads%2Fdetails.aspx%3Ffamilyid%3D457b17b7-52bf-4bda-87a3-fa8a4673f8bf&amp;amp;ei=igM8SbX_MojaM8-R2a8F&amp;amp;usg=AFQjCNE5i8Ndl2AZGRxmQ8seQB1MZawSVA&amp;amp;sig2=3w05HjQyqEhCJaSEFkrewA"&gt;download&lt;/a&gt; for
free. This allows us to create the Deep Zoom images and even allows us to create a
collage of image in Deep Zoom. We will be doing the latter, using the numerous amount
of photos that I took while traveling through Europe for the month of September. 
&lt;/p&gt;
&lt;p&gt;
The first thing we need to do is create a new project in Deep Zoom Composer. Do this
by running the Deep Zoom Composer and selecting new project. After doing this you
will see three tabs along the top – Import, Compose, and Export. If you are not already
on the Import tab, select it, and then we need to add the images that we want to work
with. In my case I will be adding in all my pictures from Rome. Click the Add Image…
button on the right and select the images that you want to add. Remember that you
can select multiple images at once to get your images imported in faster. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa1.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Once the images are imported we then switch over to the Compose tab. The tab allows
you to create how the final image will look in your Silverlight Application. Select
your imported images from the side and place them on the canvas how you would like
them to appear. You can zoom in and out on the canvas and place your photos at different
depths, even embedding them within each other. For instance I have an image of the
Coliseum from the distance with a sign that is on the side of it. I then have a closer
image of that sign as another picture. The Deep Zoom composer allows me to embed the
more detailed image of the sign into the image of the Coliseum. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa2.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa3.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
In the composer you also have the ability to associate tags with the images. I have
associated various tags with all my images. Through the composer you can only apply
one string as a tag, so I have used this field to enter multiple "tags" separated
by commas. In a future tutorial I will demonstrate how to create a tag filter to filter
down images shown in the MultiScaleImage. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa4.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Once we have exported the images from Deep Zoom Composer it is now time to get our
hands dirty in Visual Studio 2008. In order to work with Silverlight 2.0 applications
you are going to need 3 things, Visual Studio 2008 SP1, the Silverlight SDK, and the
Silverlight tools for Visual Studio 2008. Fire up vs2008, go to File-&amp;gt;New-&amp;gt;Project
and under Visual C# (or if you prefer you can select VB) select Silverlight. Then
select Silverlight Application on the right, name your solution, and select where
you want to save it. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa5.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Next a window will appear that will ask you if you want to add a new ASP.NET web project
to the solution or generate a test page at build time. Every Silverlight application
needs to be hosted inside a web application so we will let Visual Studio add a project
to our solution for this purpose. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa6.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
If you now look in the Solution Explorer you will see that we have an empty Silverlight
Application called DeepZoomExample2 and a ASP.NET web project called DeepZoomExample2.Web.
The web project has two pages that were created for us, an aspx page and a html page
that hosts our Silverlight Application. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa7.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Next we need to add our exported images to the web project. Add a new folder under
the ClientBin folder on the Web Project and call it GeneratedImages. The ClientBin
folder is where the compiled .xap file from your Silverlight will live so this is
the easiest place to put our exported files. Now go into your exported folder from
the Deep Zoom Composer and open up the generated images folder and copy the dzc_output_files
folder, and the dzc_output_images folder along with the three files, dzc_output.xml,
Metadata.xml, SparseImageSceneGraph.xml into the new GeneratedImages folder that you
created in your web project. If you used a lot of images this may take some time to
copy. Your Solution Explorer should now look like the following image. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa8.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Now it's time to start writing some code. First we add a MultiScaleImage to the Page.xaml
file. The Source property will be directed at the dzc_output.zml files that we copied
into our GeneratedImages folder. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;Grid&lt;/span&gt;&lt;span style="color:blue"&gt; &lt;/span&gt;&lt;span style="color:red"&gt;x:Name&lt;/span&gt;&lt;span style="color:blue"&gt;=&lt;/span&gt;"&lt;span style="color:blue"&gt;LayoutRoot&lt;/span&gt;"&lt;span style="color:blue"&gt; &lt;/span&gt;&lt;span style="color:red"&gt;Background&lt;/span&gt;&lt;span style="color:blue"&gt;=&lt;/span&gt;"&lt;span style="color:blue"&gt;White&lt;/span&gt;"&lt;span style="color:blue"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;MultiScaleImage&lt;/span&gt;&lt;span style="color:blue"&gt; &lt;/span&gt;&lt;span style="color:red"&gt;x:Name&lt;/span&gt;&lt;span style="color:blue"&gt;=&lt;/span&gt;"&lt;span style="color:blue"&gt;msi&lt;/span&gt;"&lt;span style="color:blue"&gt; &lt;/span&gt;&lt;span style="color:red"&gt;ViewportWidth&lt;/span&gt;&lt;span style="color:blue"&gt;=&lt;/span&gt;"&lt;span style="color:blue"&gt;1.0&lt;/span&gt;"&lt;span style="color:blue"&gt; &lt;/span&gt;&lt;span style="color:red"&gt;Source&lt;/span&gt;&lt;span style="color:blue"&gt;=&lt;/span&gt;"&lt;span style="color:blue"&gt;/GeneratedImages/dzc_output.xml&lt;/span&gt;"&lt;span style="color:blue"&gt; /&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;Grid&lt;/span&gt;&lt;span style="color:blue"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
This is all we need to do to get the basic images on the screen, but that isn't very
exciting so lets wire up some zooming using the mouse button. In the Page.xaml.cs
file we need to add a few variables to store some information: 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="color:green; font-family:Courier New; font-size:10pt"&gt;//This variable
is used to know if the user has just click the left button or has clicked and dragged &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:blue"&gt;bool&lt;/span&gt; mouseIsDragging
= &lt;span style="color:blue"&gt;false&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Indicates
if left mouse button is down &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:blue"&gt;bool&lt;/span&gt; mouseButtonPressed
= &lt;span style="color:blue"&gt;false&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Starting
Point of the Drag &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Point&lt;/span&gt; dragOffset; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Get
Current ViewPort position of MSI &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Point&lt;/span&gt; currentPosition; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Last
Position of Mouse &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Point&lt;/span&gt; lastMousePos
= &lt;span style="color:blue"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Point&lt;/span&gt;(); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;double&lt;/span&gt; ZoomFactor &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;get&lt;/span&gt;; &lt;span style="color:blue"&gt;set&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
We then have three mouse events that we need to handle, LeftMouseButton down, LeftMouseButton
up, and Mouse Move. Then we need to handle the actual zoom. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; Handles
Left Mouse button down event &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;/summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="sender"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="e"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; LeftMouseButtonDownHandler(&lt;span style="color:blue"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af"&gt;MouseEventArgs&lt;/span&gt; e) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Indicate
that the button is down &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; mouseButtonPressed = &lt;span style="color:blue"&gt;true&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Reset
Dragging &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; mouseIsDragging = &lt;span style="color:blue"&gt;false&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Set
Starting point of the drag if the user start dragging &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; dragOffset = e.GetPosition(&lt;span style="color:blue"&gt;this&lt;/span&gt;); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; currentPosition = msi.ViewportOrigin; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
In the left mouse button down even, we first set the indicator that the button is
pressed. We then reset the dragging indicator, get the current position of the mouse,
and finally get the current position of the MultiScaleImage. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; Handles
Left Mouse button up event &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;/summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="sender"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="e"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; LeftMouseButtonUpHandler(&lt;span style="color:blue"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af"&gt;MouseEventArgs&lt;/span&gt; e) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Change
flag to mouse button no longer pressed &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; mouseButtonPressed = &lt;span style="color:blue"&gt;false&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//If
the user wasn't dragging then we do zooming &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt;(!mouseIsDragging) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Check
if shift was pressed. If so we zoom out, otherwise we zoom in &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;bool&lt;/span&gt; shiftDown
= (&lt;span style="color:#2b91af"&gt;Keyboard&lt;/span&gt;.Modifiers &amp;amp; &lt;span style="color:#2b91af"&gt;ModifierKeys&lt;/span&gt;.Shift)
== &lt;span style="color:#2b91af"&gt;ModifierKeys&lt;/span&gt;.Shift; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; ZoomFactor = 2.0; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt; (shiftDown)
ZoomFactor = 0.5; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; Zoom(ZoomFactor, &lt;span style="color:blue"&gt;this&lt;/span&gt;.lastMousePos); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
When the left mouse button is lifted we change the flag that indicates that the left
mouse button is down and if the user was not dragging. We then check to see if shift
was pressed. If shift was not pressed we zoom in by a factor of 2, but if shift was
pressed we zoom out by a factor of .5. We then call our zoom function (which we have
yet to create) with the zoom factor and the last point the mouse was at. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p style="margin-left: 36pt"&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:gray"&gt; ///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; Handlers
the moving of the mouse &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;/summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="sender"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="e"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; MouseMoveHandler(&lt;span style="color:blue"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af"&gt;MouseEventArgs&lt;/span&gt; e) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.lastMousePos
= e.GetPosition(&lt;span style="color:blue"&gt;this&lt;/span&gt;.msi); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
With the mouse move function all we need to do is capture the position that the mouse
is at. Finally in the below Zoom function that is called from the LeftMouseButtonUpHandler,
we do the actual zooming. 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; Zoom(&lt;span style="color:blue"&gt;double&lt;/span&gt; zoom, &lt;span style="color:#2b91af"&gt;Point&lt;/span&gt; pointToZoom) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:#2b91af"&gt;Point&lt;/span&gt; logicalPoint
= &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.ElementToLogicalPoint(pointToZoom); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.ZoomAboutLogicalPoint(zoom,
logicalPoint.X, logicalPoint.Y); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see above we have to translate the mouse pointer relative to our MultiScaleImage
and then we use the ZoomAboutLogicalPoint method to handle the zooming for us. The
last thing we need to do is wire up the events to the MultiScaleImage control in the
Page constructor which will look like the following: 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;public&lt;/span&gt; Page() &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; InitializeComponent(); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Wire
up events &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.MouseLeftButtonDown
+= LeftMouseButtonDownHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.MouseLeftButtonUp
+= LeftMouseButtonUpHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.MouseMove
+= MouseMoveHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
If you now run the application you will get the layout of all images on your screen
as seen in the first picture below, and if I click on the picture of St. Peter's Square
in the center of the image the MultiScaleImage control will zoom in on that particular
image as seen in the second picture below. Holding down the shift key while clicking
will zoom the MultiScaleImage back out. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa9.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/120708_1721_DeepZoomExa10.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
In order to enable panning we need to augment a few functions that we have already
created. Obviously we need to modify the MouseMoveHandler. Initially all this event
was doing was updating the mouse position so that when we zoomed in or out we knew
where the mouse was pointing. Now we are going to have it check to see if the mouse
button is down to indicate that dragging is occurring. Also if the mouse is dragging
we need to update the position so that the MultiScaleImage is centered on to where
the mouse is dragging. Our new MouseMoveHandler appears below. 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; Handlers
the moving of the mouse &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;/summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="sender"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="e"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; MouseMoveHandler(&lt;span style="color:blue"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af"&gt;MouseEventArgs&lt;/span&gt; e) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt;(mouseButtonPressed) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; mouseIsDragging = &lt;span style="color:blue"&gt;true&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.lastMousePos
= e.GetPosition(&lt;span style="color:blue"&gt;this&lt;/span&gt;.msi); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Update
this View of the MultiScaleImage is dragging &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt;(mouseIsDragging) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:#2b91af"&gt;Point&lt;/span&gt; newOrigin
= &lt;span style="color:blue"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Point&lt;/span&gt;(); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; newOrigin.X = currentPosition.X
- &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; (((e.GetPosition(msi).X - dragOffset.X)/msi.ActualWidth)*msi.ViewportWidth); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; newOrigin.Y = currentPosition.Y
- &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; (((e.GetPosition(msi).Y - dragOffset.Y)/msi.ActualWidth)*msi.ViewportWidth); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; msi.ViewportOrigin = newOrigin; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
In our left mouse button down handler we are already handling the dragging functionality
by initializing the mouseIsDragging variable to false, and setting dargOffset to the
initial point that the mouse was at when dragging was started. In the left mouse button
up handler we need to update the dragging indicator that was set to true in the left
mouse button down indicated. The new handler appears below: 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; Handles
Left Mouse button up event &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;/summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="sender"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="e"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; LeftMouseButtonUpHandler(&lt;span style="color:blue"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af"&gt;MouseEventArgs&lt;/span&gt; e) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Change
flag to mouse button no longer pressed &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; mouseButtonPressed = &lt;span style="color:blue"&gt;false&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//If
the user wasn't dragging then we do zooming &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt;(!mouseIsDragging) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Check
if shift was pressed. If so we zoom out, otherwise we zoom in &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;bool&lt;/span&gt; shiftDown
= (&lt;span style="color:#2b91af"&gt;Keyboard&lt;/span&gt;.Modifiers &amp;amp; &lt;span style="color:#2b91af"&gt;ModifierKeys&lt;/span&gt;.Shift)
== &lt;span style="color:#2b91af"&gt;ModifierKeys&lt;/span&gt;.Shift; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; ZoomFactor = 2.0; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt; (shiftDown)
ZoomFactor = 0.5; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; Zoom(ZoomFactor, &lt;span style="color:blue"&gt;this&lt;/span&gt;.lastMousePos); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; mouseIsDragging = &lt;span style="color:blue"&gt;false&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
We now need to add one more handler. If the mouse goes outside the MultiScaleImage
we what to stop the panning so we need to add a Mouse Leave event handler. In the
handler I am also going to reset the mouse down variable when the user leaves the
MultiScaleImage. This way if they leave the image, lift up the mouse button, and re-enter
the image, it won't continue to pan. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; Handles
the mouse leave event &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;/summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="sender"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="e"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; MouseLeaveHandler(&lt;span style="color:blue"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af"&gt;MouseEventArgs&lt;/span&gt; e) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; mouseIsDragging = &lt;span style="color:blue"&gt;false&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; mouseButtonPressed = &lt;span style="color:blue"&gt;false&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
We now need to assign the event, so in the constructor where we wired up the other
events we need to also wire up the MouseLeave event of the MultiScaleImage: 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;public&lt;/span&gt; Page() &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; InitializeComponent(); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Wire
up events &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.MouseLeftButtonDown
+= LeftMouseButtonDownHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.MouseLeftButtonUp
+= LeftMouseButtonUpHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.MouseMove
+= MouseMoveHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.MouseLeave
+= MouseLeaveHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
There you go. Adding panning was that easy. Now if you fire up the site you can click
and dragging the image around and still zoom in and out using click and shit click. 
&lt;/p&gt;
&lt;p&gt;
The next thing we need to do is add zooming with the scroll wheel. We are going to
do this by using the MouseWheelHelper class provided by &lt;a href="http://blois.us/blog/2008/03/ive-heard-number-of-people-wondering.html"&gt;Peter
Blois&lt;/a&gt;. So grab this class and add it to your Silverlight Application. With Silverlight
2.0 the silverlight application can reach into the DOM using the Sliverlight DOM bridge
and listen to events in the class, abstracting that away from us. 
&lt;/p&gt;
&lt;p&gt;
The first thing we need to do is create an event to handle the mouse wheel. Inside
this event we set the event to handled so that the system knows that the event has
be taken care of, we set the zoom factor by checking the Delta value that is passed
to us from the MouseWheelHelper class. Finally we call the Zoom method passing the
factor that we want to zoom by and the point we are zooming at, just like if the user
had clicked the mouse button to zoom. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; Handles
the mouse wheel events &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;/summary&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="sender"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; &lt;/span&gt;&lt;span style="color:gray"&gt;&amp;lt;param
name="e"&amp;gt;&amp;lt;/param&amp;gt; &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; MouseWheelHandler(&lt;span style="color:blue"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af"&gt;MouseWheelEventArgs&lt;/span&gt; e) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Notify
that we handled the event &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; e.Handled = &lt;span style="color:blue"&gt;true&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; ZoomFactor = e.Delta &amp;gt; 0
? 1.2 : .80; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; Zoom(ZoomFactor, &lt;span style="color:blue"&gt;this&lt;/span&gt;.lastMousePos); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Lastly we wire up with event in our constructor just below where we we wiring up the
rest of the events. The newly modify constructor appears as follows: 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;public&lt;/span&gt; Page() &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; InitializeComponent(); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Wire
up events &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.MouseLeftButtonDown
+= LeftMouseButtonDownHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.MouseLeftButtonUp
+= LeftMouseButtonUpHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.MouseMove
+= MouseMoveHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;this&lt;/span&gt;.msi.MouseLeave
+= MouseLeaveHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;MouseWheelHelper&lt;/span&gt;(&lt;span style="color:blue"&gt;this&lt;/span&gt;).Moved
+= MouseWheelHandler; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
If you now build and run the application you'll see that the ability to have zoom
with the scroll wheel of the mouse is now present. Hopefully this has demonstrated
that working with the Deep Zoom functionality and Deem Zoom Composer is fairly simple
and can greatly enhance the user experience for a web site. The even better news is
that Deep Zoom composer will now generate all this functionality for you wrapped into
a Silverlight 2.0 application when you export your Deep Zoom image. This particular
sample was pieced together from what I learned from &lt;a href="http://blog.kirupa.com/"&gt;Kirupa
Chinnathambi blog&lt;/a&gt; who is currently a member of the Expression Blend team at Microsoft. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=2da2f1cf-b0be-487d-b5b4-4df5aa379407" /&gt;</description>
      <comments>http://weblog.ctrlalt313373.com/CommentView,guid,2da2f1cf-b0be-487d-b5b4-4df5aa379407.aspx</comments>
      <category>Deep Zoom</category>
      <category>Deep Zoom Composer</category>
      <category>Development</category>
      <category>Silverlight</category>
    </item>
    <item>
      <trackback:ping>http://weblog.ctrlalt313373.com/Trackback.aspx?guid=8642ec34-1b48-4ac1-9245-3edd65ae1cf5</trackback:ping>
      <pingback:server>http://weblog.ctrlalt313373.com/pingback.aspx</pingback:server>
      <pingback:target>http://weblog.ctrlalt313373.com/PermaLink,guid,8642ec34-1b48-4ac1-9245-3edd65ae1cf5.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://weblog.ctrlalt313373.com/CommentView,guid,8642ec34-1b48-4ac1-9245-3edd65ae1cf5.aspx</wfw:comment>
      <wfw:commentRss>http://weblog.ctrlalt313373.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8642ec34-1b48-4ac1-9245-3edd65ae1cf5</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm really getting tired of waiting for computers to do things; boot, shutdown, open
Visual Studio, build. I feel like I spend more time waiting for the computer to do
something then actually getting work done and this is very frustrating. I like my
laptop and unfortunately it's not dual core, but I've decided that for the amount
of mobility that I need it can still handle the job. What I do what to do is build
a new desktop development box that I can use when working in the office since this
is where I do most of my work, outside of the day job anyways. I've gotten a bit out
of touch with the hardware world lately so I was hoping to solicit some feedback in
a few areas. Here is a list of the general specs I've laid out. 
</p>
        <p>
        </p>
        <p>
          <strong>Quad Core Processor </strong>– I realize that this is still a bit vague since
some argue that a dual core with a faster speed is better that a slower quad core,
but I hope to get the fastest quad core processor for a reasonable price when I make
the purchase. 
</p>
        <p>
          <strong>Motherboard</strong> – This is where I've gotten a bit rusty. Does anyone
have any suggestions on brands and specs that I want to look for? 
</p>
        <p>
          <strong>Vista Ultimate 64 bit </strong>– Yeah, Yeah don't do it, Vista sucks. I'm
going to do it anyways. 
</p>
        <p>
          <strong>4GB of RAM </strong>– Anything important here besides speed and response time? 
</p>
        <p>
          <strong>16-30GB Solid State Hard Drive </strong>– This one I think is the sweet spot.
The last moving part on the computer is the hard drive and common sense says that
means it's the real bottleneck. I hope to get a small solid state hd that will hold
the OS, VS2008, and maybe Office depending on price vs size. My one issue here is
I haven't seen any 3.5 inch solid state drives. 
</p>
        <p>
          <strong>Large Secondary Hard Drive</strong> – A regular SATA hard drive to handle
everything else that isn't used all the time. I'm thinking a WD Raptor for this. 
</p>
        <p>
          <strong>Video Card(s) – </strong>Yet again I'm going to need to do some research here
or get some feedback. What specs do I need to look for here? 
</p>
        <p>
          <strong>2 X 22 inch Widescreen Monitors</strong> – I haven't decided on anything specifics
here, I just know I want 2 that are exactly the same so they are at the same level. 
</p>
        <p>
          <strong>Case</strong> – A really, really quiet case. This is going to involve research
too. 
</p>
        <p>
        </p>
        <p>
Any feedback that anyone has would be great. 
</p>
        <p>
        </p>
        <img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=8642ec34-1b48-4ac1-9245-3edd65ae1cf5" />
      </body>
      <title>Thinking About a New Machine</title>
      <guid isPermaLink="false">http://weblog.ctrlalt313373.com/PermaLink,guid,8642ec34-1b48-4ac1-9245-3edd65ae1cf5.aspx</guid>
      <link>http://weblog.ctrlalt313373.com/2008/04/08/ThinkingAboutANewMachine.aspx</link>
      <pubDate>Tue, 08 Apr 2008 02:01:36 GMT</pubDate>
      <description>&lt;p&gt;
I'm really getting tired of waiting for computers to do things; boot, shutdown, open
Visual Studio, build. I feel like I spend more time waiting for the computer to do
something then actually getting work done and this is very frustrating. I like my
laptop and unfortunately it's not dual core, but I've decided that for the amount
of mobility that I need it can still handle the job. What I do what to do is build
a new desktop development box that I can use when working in the office since this
is where I do most of my work, outside of the day job anyways. I've gotten a bit out
of touch with the hardware world lately so I was hoping to solicit some feedback in
a few areas. Here is a list of the general specs I've laid out. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Quad Core Processor &lt;/strong&gt;– I realize that this is still a bit vague since
some argue that a dual core with a faster speed is better that a slower quad core,
but I hope to get the fastest quad core processor for a reasonable price when I make
the purchase. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Motherboard&lt;/strong&gt; – This is where I've gotten a bit rusty. Does anyone
have any suggestions on brands and specs that I want to look for? 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Vista Ultimate 64 bit &lt;/strong&gt;– Yeah, Yeah don't do it, Vista sucks. I'm
going to do it anyways. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;4GB of RAM &lt;/strong&gt;– Anything important here besides speed and response time? 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;16-30GB Solid State Hard Drive &lt;/strong&gt;– This one I think is the sweet spot.
The last moving part on the computer is the hard drive and common sense says that
means it's the real bottleneck. I hope to get a small solid state hd that will hold
the OS, VS2008, and maybe Office depending on price vs size. My one issue here is
I haven't seen any 3.5 inch solid state drives. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Large Secondary Hard Drive&lt;/strong&gt; – A regular SATA hard drive to handle
everything else that isn't used all the time. I'm thinking a WD Raptor for this. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Video Card(s) – &lt;/strong&gt;Yet again I'm going to need to do some research here
or get some feedback. What specs do I need to look for here? 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;2 X 22 inch Widescreen Monitors&lt;/strong&gt; – I haven't decided on anything specifics
here, I just know I want 2 that are exactly the same so they are at the same level. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Case&lt;/strong&gt; – A really, really quiet case. This is going to involve research
too. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Any feedback that anyone has would be great. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=8642ec34-1b48-4ac1-9245-3edd65ae1cf5" /&gt;</description>
      <comments>http://weblog.ctrlalt313373.com/CommentView,guid,8642ec34-1b48-4ac1-9245-3edd65ae1cf5.aspx</comments>
      <category>Development</category>
      <category>Hardware</category>
    </item>
    <item>
      <trackback:ping>http://weblog.ctrlalt313373.com/Trackback.aspx?guid=b7804d2e-f1ef-4b30-a210-33ddda9da810</trackback:ping>
      <pingback:server>http://weblog.ctrlalt313373.com/pingback.aspx</pingback:server>
      <pingback:target>http://weblog.ctrlalt313373.com/PermaLink,guid,b7804d2e-f1ef-4b30-a210-33ddda9da810.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://weblog.ctrlalt313373.com/CommentView,guid,b7804d2e-f1ef-4b30-a210-33ddda9da810.aspx</wfw:comment>
      <wfw:commentRss>http://weblog.ctrlalt313373.com/SyndicationService.asmx/GetEntryCommentsRss?guid=b7804d2e-f1ef-4b30-a210-33ddda9da810</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Well its official <a href="http://blogs.giffordconsulting.com">The Gifford</a> has
turned me into a code coverage addict. After he helped me through writing my first
unit test using <a href="http://www.nunit.org/index.php">NUnit</a> the concept slowly
started sinking in and I'm now addicted to code coverage. Writing NUnit tests is so
easy that I don't understand why everyone won't do it, which is causing me to get
a bit frustrated with people as it gives me the impression that they just don't care.
I can't remember the number of times that I have gotten rather pissed because someone
has changed my code and broken functionality and in some cases I've even broken my
own code when I've had to go in and make changes after not looking at it for some
time. Unit testing can <strong>minimize</strong> these hair pulling moments by giving
you more confidence that what was supposed to be happening before you touched the
code still happens after you touched it. If someone is in muddling around in your
code and breaks something, you'll know immediately when they check in and the test
doesn't pass on the build server. It all comes down to code quality and I have begun
to notice recently that code quality everywhere sucks. 
</p>
        <p>
If you're not using unit testing of some sort then I think it just boils down to pure
ignorance. Either you see the value of unit tests, but don't know how to write them
and are too lazy to exert the effort to learn how, or you are just too ignorant to
see the value of them. I fell into the first group. I've always seen how they could
be helpful, but never took the time to learn how to do them. In the last couple weeks
I've been really thinking about code quality with the product that I am building with
a couple partners. We decided to build this product because we had gotten stuck working
with another product that we thought had many problems and was a pain to work with.
I realized that we were starting to walk down the same path, rushing to get a beta
out, sacrificing design and architecture for deadlines. There are plenty of poor applications
on the market and I don't want to be contributing to that. I want to produce a quality
product or nothing at all because in the long run if we produce a poor quality product
then we get stuck supporting that poor quality and our customers are stuck working
with it. While assessing quality I kept coming back to our lack of unit testing and
the fact that things kept breaking that worked fine the day before. This motivated
me to overhaul the build server so that it runs NUnit tests automatically and then
uses <a href="http://www.ncover.com/">NCover</a> to provide statistics on the code
that is covered by unit tests and the code that is not covered. Then to take it one
step further I built a screensaver that runs on the monitor of the build server that
displays the overall percent of code coverage from the project in bright flashing
red while it is under the coverage goal. (Currently <a href="http://www.flofactory.com">FloFactory</a> is
at 9.5% code coverage with a coverage goal of 50%.) I look forward to the day that
that text turns green to indicate that we have met our code coverage goal (and then
I'll raise the goal). 
</p>
        <p>
I'm sure plenty of people would argue about the value of unit testing, pointing out
various short coming with unit testing which I am sure are all valid in certain scenarios,
but if you're following a tiered structure for your application, keep your logic out
of the UI and keep your data access separate, then you should have an entire service
layer that can be unit tested. Does having unit tests mean your code is perfect, of
course not. It's not a silver bullet for quality but it is one tool to provide a bit
more certainty about an application. 
</p>
        <p>
Where I am really struggling is motivating others to improve their code quality, understanding
the importance of testing and getting them to write even one unit test. I realize
that unit testing can't cover your entire application, but it's a start and if you
start thinking about how you structure your application you'll starting seeing better
ways to design things so that you can properly test them using such things as mock
objects and inversion of control containers. <a href="http://blogs.giffordconsulting.com">The
Gifford</a> told me once that he goes by the statement "You don't have write unit
tests, but don't break mine." Whereas I like this statement, I don't think it motives
any one to write a single unit test, so I'm adding onto this by trying to make the
statistics more visible. Hopefully if someone checks in code that lowers the overall
coverage percent, that they can see very clearly on the build server screensaver,
they may feel more motivated to raise that number. 
</p>
        <p>
As for myself, I'm going to keep digging into ways to increase quality so that the
final product is stable and worth using. One last thing to point out is that if you
plan to get started unit testing and are going to use NUnit then I would suggest picking
up a copy of <a href="http://www.jetbrains.com/resharper/">Resharper</a>. It allows
you to run your NUnit tests extremely easily from Visual Studio taking some of the
headaches out of writing them.
</p>
        <img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=b7804d2e-f1ef-4b30-a210-33ddda9da810" />
      </body>
      <title>Code Coverage Addict</title>
      <guid isPermaLink="false">http://weblog.ctrlalt313373.com/PermaLink,guid,b7804d2e-f1ef-4b30-a210-33ddda9da810.aspx</guid>
      <link>http://weblog.ctrlalt313373.com/2008/03/17/CodeCoverageAddict.aspx</link>
      <pubDate>Mon, 17 Mar 2008 00:39:55 GMT</pubDate>
      <description>&lt;p&gt;
Well its official &lt;a href="http://blogs.giffordconsulting.com"&gt;The Gifford&lt;/a&gt; has
turned me into a code coverage addict. After he helped me through writing my first
unit test using &lt;a href="http://www.nunit.org/index.php"&gt;NUnit&lt;/a&gt; the concept slowly
started sinking in and I'm now addicted to code coverage. Writing NUnit tests is so
easy that I don't understand why everyone won't do it, which is causing me to get
a bit frustrated with people as it gives me the impression that they just don't care.
I can't remember the number of times that I have gotten rather pissed because someone
has changed my code and broken functionality and in some cases I've even broken my
own code when I've had to go in and make changes after not looking at it for some
time. Unit testing can &lt;strong&gt;minimize&lt;/strong&gt; these hair pulling moments by giving
you more confidence that what was supposed to be happening before you touched the
code still happens after you touched it. If someone is in muddling around in your
code and breaks something, you'll know immediately when they check in and the test
doesn't pass on the build server. It all comes down to code quality and I have begun
to notice recently that code quality everywhere sucks. 
&lt;/p&gt;
&lt;p&gt;
If you're not using unit testing of some sort then I think it just boils down to pure
ignorance. Either you see the value of unit tests, but don't know how to write them
and are too lazy to exert the effort to learn how, or you are just too ignorant to
see the value of them. I fell into the first group. I've always seen how they could
be helpful, but never took the time to learn how to do them. In the last couple weeks
I've been really thinking about code quality with the product that I am building with
a couple partners. We decided to build this product because we had gotten stuck working
with another product that we thought had many problems and was a pain to work with.
I realized that we were starting to walk down the same path, rushing to get a beta
out, sacrificing design and architecture for deadlines. There are plenty of poor applications
on the market and I don't want to be contributing to that. I want to produce a quality
product or nothing at all because in the long run if we produce a poor quality product
then we get stuck supporting that poor quality and our customers are stuck working
with it. While assessing quality I kept coming back to our lack of unit testing and
the fact that things kept breaking that worked fine the day before. This motivated
me to overhaul the build server so that it runs NUnit tests automatically and then
uses &lt;a href="http://www.ncover.com/"&gt;NCover&lt;/a&gt; to provide statistics on the code
that is covered by unit tests and the code that is not covered. Then to take it one
step further I built a screensaver that runs on the monitor of the build server that
displays the overall percent of code coverage from the project in bright flashing
red while it is under the coverage goal. (Currently &lt;a href="http://www.flofactory.com"&gt;FloFactory&lt;/a&gt; is
at 9.5% code coverage with a coverage goal of 50%.) I look forward to the day that
that text turns green to indicate that we have met our code coverage goal (and then
I'll raise the goal). 
&lt;/p&gt;
&lt;p&gt;
I'm sure plenty of people would argue about the value of unit testing, pointing out
various short coming with unit testing which I am sure are all valid in certain scenarios,
but if you're following a tiered structure for your application, keep your logic out
of the UI and keep your data access separate, then you should have an entire service
layer that can be unit tested. Does having unit tests mean your code is perfect, of
course not. It's not a silver bullet for quality but it is one tool to provide a bit
more certainty about an application. 
&lt;/p&gt;
&lt;p&gt;
Where I am really struggling is motivating others to improve their code quality, understanding
the importance of testing and getting them to write even one unit test. I realize
that unit testing can't cover your entire application, but it's a start and if you
start thinking about how you structure your application you'll starting seeing better
ways to design things so that you can properly test them using such things as mock
objects and inversion of control containers. &lt;a href="http://blogs.giffordconsulting.com"&gt;The
Gifford&lt;/a&gt; told me once that he goes by the statement "You don't have write unit
tests, but don't break mine." Whereas I like this statement, I don't think it motives
any one to write a single unit test, so I'm adding onto this by trying to make the
statistics more visible. Hopefully if someone checks in code that lowers the overall
coverage percent, that they can see very clearly on the build server screensaver,
they may feel more motivated to raise that number. 
&lt;/p&gt;
&lt;p&gt;
As for myself, I'm going to keep digging into ways to increase quality so that the
final product is stable and worth using. One last thing to point out is that if you
plan to get started unit testing and are going to use NUnit then I would suggest picking
up a copy of &lt;a href="http://www.jetbrains.com/resharper/"&gt;Resharper&lt;/a&gt;. It allows
you to run your NUnit tests extremely easily from Visual Studio taking some of the
headaches out of writing them.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=b7804d2e-f1ef-4b30-a210-33ddda9da810" /&gt;</description>
      <comments>http://weblog.ctrlalt313373.com/CommentView,guid,b7804d2e-f1ef-4b30-a210-33ddda9da810.aspx</comments>
      <category>Development</category>
      <category>NUnit</category>
      <category>Testing</category>
      <category>Unit Testing</category>
    </item>
    <item>
      <trackback:ping>http://weblog.ctrlalt313373.com/Trackback.aspx?guid=e3b53112-1821-4a62-aa13-efa9d26afbdd</trackback:ping>
      <pingback:server>http://weblog.ctrlalt313373.com/pingback.aspx</pingback:server>
      <pingback:target>http://weblog.ctrlalt313373.com/PermaLink,guid,e3b53112-1821-4a62-aa13-efa9d26afbdd.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://weblog.ctrlalt313373.com/CommentView,guid,e3b53112-1821-4a62-aa13-efa9d26afbdd.aspx</wfw:comment>
      <wfw:commentRss>http://weblog.ctrlalt313373.com/SyndicationService.asmx/GetEntryCommentsRss?guid=e3b53112-1821-4a62-aa13-efa9d26afbdd</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
So far I have went over how to <a href="http://weblog.ctrlalt313373.com/2007/12/27/CreatingARegExActivityForWindowsWorkflow.aspx">create
a basic workflow activity</a> that evaluates a regular expression against a string
and I have also covered <a href="http://weblog.ctrlalt313373.com/2007/12/29/AddingValidationToACustomWorkflowActivity.aspx">creating
the validation class</a> for the activity. The next thing I want to cover are some
basics to enhancing the designer experience of the workflow activity allowing you
to override the default visual display in the designer for a custom activity. Based
on the default designer class our RegEx activity appears as follows: 
</p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/012108_0237_Modifyingth1.png" alt="" />
        </p>
        <p>
The first thing that needs to be done is to add a new class to the project called
RegExDesigner.cs. 
</p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/012108_0237_Modifyingth2.png" alt="" />
        </p>
        <p>
        </p>
        <p>
Next we need to make our new class inherit from the ActivityDesigner class. To do
this we will also need to import the namespace <span style="font-family:Courier New; font-size:10pt">System.Workflow.ComponentModel.Design, </span>which
means your code should now appear as follows: 
</p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">using</span> System.Workflow.ComponentModel.Design; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">namespace</span> FloFactory.Activities.Util.Logic </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">{ </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">class</span>
            <span style="color:#2b91af">RegExDesigner</span> : <span style="color:#2b91af">ActivityDesigner </span></span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">} </span>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
There are a lot of functions that you can override, but the main function that we
are going to work with is the Initialize function which will allow us to override
the appearance of our activity in the designer. This first thing that I am going to
do is add a nice image to the activity. Assuming you already have an image that you
want to use as a resource in your project you add the image to the activity's design
view by doing the following: 
</p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">protected</span>
            <span style="color:blue">override</span>
            <span style="color:blue">void</span> Initialize(System.Workflow.ComponentModel.<span style="color:#2b91af">Activity</span> activity) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">base</span>.Initialize(activity); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:#2b91af">Bitmap</span> WorkFlowImage
= Properties.<span style="color:#2b91af">Resources</span>.workflow; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> Image = WorkFlowImage; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
          </span>The other thing I would
like to do is change the text that appears in the activity. This will be the default
text that shows up until the user of our activity sets the name property. This is
easily done by setting the Text property in the Initialize function. After doing this
the code should appear as follows: 
</p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">protected</span>
            <span style="color:blue">override</span>
            <span style="color:blue">void</span> Initialize(System.Workflow.ComponentModel.<span style="color:#2b91af">Activity</span> activity) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">base</span>.Initialize(activity); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:#2b91af">Bitmap</span> WorkFlowImage
= Properties.<span style="color:#2b91af">Resources</span>.workflow; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> Image = WorkFlowImage; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:green">//Set
the Text That appears </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> Text = <span style="color:#a31515">"FloFactory
RegEx"</span>; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
          </span>Now we need to associate
the designer class with our activity. We do this by going to the top of the RegEx.cs
class and add the following attribute:<span style="font-family:Courier New; font-size:10pt"></span></p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> [<span style="color:#2b91af">Designer</span>(<span style="color:blue">typeof</span>(<span style="color:#2b91af">RegExDesigner</span>), <span style="color:blue">typeof</span>(<span style="color:#2b91af">IDesigner</span>))] </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">partial</span>
            <span style="color:blue">class</span>
            <span style="color:#2b91af">RegEx</span>: <span style="color:#2b91af">BaseActivity </span></span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> … </span>
        </p>
        <p style="margin-left: 36pt">
          <span style="font-family:Courier New; font-size:10pt">} </span>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
          </span>After adding this code
to the Initialize function and adding the attribute if we now look at the RegEx activity
we will see that our image has replaced the default image that appeared when the original
designer class was applied to the RegEx activity. Also, the default text that was
defined appears in the center of the activity. 
</p>
        <p>
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/012108_0237_Modifyingth3.png" alt="" />
        </p>
        <p>
        </p>
        <p>
As you can see we have easily modified the image and the text that appears in the
designer for our RegEx activity. In a future post I will cover modifying the appearance
of the activity by changing its size and colors so as to create a more custom look
and feel for the activity. 
</p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
          </span>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
          </span>
        </p>
        <img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=e3b53112-1821-4a62-aa13-efa9d26afbdd" />
      </body>
      <title>Modifying the Designer Appearance of the RegEx Activity</title>
      <guid isPermaLink="false">http://weblog.ctrlalt313373.com/PermaLink,guid,e3b53112-1821-4a62-aa13-efa9d26afbdd.aspx</guid>
      <link>http://weblog.ctrlalt313373.com/2008/01/21/ModifyingTheDesignerAppearanceOfTheRegExActivity.aspx</link>
      <pubDate>Mon, 21 Jan 2008 02:38:13 GMT</pubDate>
      <description>&lt;p&gt;
So far I have went over how to &lt;a href="http://weblog.ctrlalt313373.com/2007/12/27/CreatingARegExActivityForWindowsWorkflow.aspx"&gt;create
a basic workflow activity&lt;/a&gt; that evaluates a regular expression against a string
and I have also covered &lt;a href="http://weblog.ctrlalt313373.com/2007/12/29/AddingValidationToACustomWorkflowActivity.aspx"&gt;creating
the validation class&lt;/a&gt; for the activity. The next thing I want to cover are some
basics to enhancing the designer experience of the workflow activity allowing you
to override the default visual display in the designer for a custom activity. Based
on the default designer class our RegEx activity appears as follows: 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/012108_0237_Modifyingth1.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
The first thing that needs to be done is to add a new class to the project called
RegExDesigner.cs. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/012108_0237_Modifyingth2.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Next we need to make our new class inherit from the ActivityDesigner class. To do
this we will also need to import the namespace &lt;span style="font-family:Courier New; font-size:10pt"&gt;System.Workflow.ComponentModel.Design, &lt;/span&gt;which
means your code should now appear as follows: 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;using&lt;/span&gt; System.Workflow.ComponentModel.Design; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;namespace&lt;/span&gt; FloFactory.Activities.Util.Logic &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;{ &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;RegExDesigner&lt;/span&gt; : &lt;span style="color:#2b91af"&gt;ActivityDesigner &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;} &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
There are a lot of functions that you can override, but the main function that we
are going to work with is the Initialize function which will allow us to override
the appearance of our activity in the designer. This first thing that I am going to
do is add a nice image to the activity. Assuming you already have an image that you
want to use as a resource in your project you add the image to the activity's design
view by doing the following: 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;protected&lt;/span&gt; &lt;span style="color:blue"&gt;override&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; Initialize(System.Workflow.ComponentModel.&lt;span style="color:#2b91af"&gt;Activity&lt;/span&gt; activity) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;base&lt;/span&gt;.Initialize(activity); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:#2b91af"&gt;Bitmap&lt;/span&gt; WorkFlowImage
= Properties.&lt;span style="color:#2b91af"&gt;Resources&lt;/span&gt;.workflow; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; Image = WorkFlowImage; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;/span&gt;The other thing I would
like to do is change the text that appears in the activity. This will be the default
text that shows up until the user of our activity sets the name property. This is
easily done by setting the Text property in the Initialize function. After doing this
the code should appear as follows: 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;protected&lt;/span&gt; &lt;span style="color:blue"&gt;override&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; Initialize(System.Workflow.ComponentModel.&lt;span style="color:#2b91af"&gt;Activity&lt;/span&gt; activity) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;base&lt;/span&gt;.Initialize(activity); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:#2b91af"&gt;Bitmap&lt;/span&gt; WorkFlowImage
= Properties.&lt;span style="color:#2b91af"&gt;Resources&lt;/span&gt;.workflow; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; Image = WorkFlowImage; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:green"&gt;//Set
the Text That appears &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; Text = &lt;span style="color:#a31515"&gt;"FloFactory
RegEx"&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;/span&gt;Now we need to associate
the designer class with our activity. We do this by going to the top of the RegEx.cs
class and add the following attribute:&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; [&lt;span style="color:#2b91af"&gt;Designer&lt;/span&gt;(&lt;span style="color:blue"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;RegExDesigner&lt;/span&gt;), &lt;span style="color:blue"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;IDesigner&lt;/span&gt;))] &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;partial&lt;/span&gt; &lt;span style="color:blue"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;RegEx&lt;/span&gt;: &lt;span style="color:#2b91af"&gt;BaseActivity &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; … &lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin-left: 36pt"&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;} &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;/span&gt;After adding this code
to the Initialize function and adding the attribute if we now look at the RegEx activity
we will see that our image has replaced the default image that appeared when the original
designer class was applied to the RegEx activity. Also, the default text that was
defined appears in the center of the activity. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/012108_0237_Modifyingth3.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see we have easily modified the image and the text that appears in the
designer for our RegEx activity. In a future post I will cover modifying the appearance
of the activity by changing its size and colors so as to create a more custom look
and feel for the activity. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;/span&gt; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=e3b53112-1821-4a62-aa13-efa9d26afbdd" /&gt;</description>
      <comments>http://weblog.ctrlalt313373.com/CommentView,guid,e3b53112-1821-4a62-aa13-efa9d26afbdd.aspx</comments>
      <category>.Net 3.0</category>
      <category>Development</category>
      <category>Windows Workflow</category>
    </item>
    <item>
      <trackback:ping>http://weblog.ctrlalt313373.com/Trackback.aspx?guid=600c401c-a5dd-4bf8-b6c1-e1f2191237b8</trackback:ping>
      <pingback:server>http://weblog.ctrlalt313373.com/pingback.aspx</pingback:server>
      <pingback:target>http://weblog.ctrlalt313373.com/PermaLink,guid,600c401c-a5dd-4bf8-b6c1-e1f2191237b8.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://weblog.ctrlalt313373.com/CommentView,guid,600c401c-a5dd-4bf8-b6c1-e1f2191237b8.aspx</wfw:comment>
      <wfw:commentRss>http://weblog.ctrlalt313373.com/SyndicationService.asmx/GetEntryCommentsRss?guid=600c401c-a5dd-4bf8-b6c1-e1f2191237b8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Well lately I have been using <a href="http://www.jetbrains.com/resharper/">Resharper</a> from <a href="http://www.jetbrains.com/">JetBrains</a> which
is an amazing Visual Studio Add in that adds an extensive amount of new features and
shortcuts. It has greatly increased my productivity and if you're not using it then
you should at least download the 30 day trial and test it out. (Greg this means you.
Tell Matt I said he should buy it for you.) I especially like the file structure explorer
that allows me to organize functions and properties in a class by dragging them around
instead of needing to copy and paste them. This is very helpful when organizing your
classes into regions. Also, if you've ever had a giant solution where it begins to
be difficult to find files you'll appreciate the file search that allows you to start
typing a filename and get a filtered list of files. It definitely can be a bit overwhelming
with all the shortcuts it adds to Visual Studio so in order to make looking up the
shortcuts easier I created this basic VS2005 add in that displays the Resharper cheat
sheet on the screen. After installing the Recheater Add in you can display the cheat
sheet by hitting CTRL-ALT-SHIFT-H and close it down by hitting the ESC key. To change
the shortcut key simply modify the config file located under My Documents\Visual Studio
2005\Addins\RecheaterAddin. It's a pretty basic application, but feel free to download <a href="http://www.ctrlalt313373.com/LinkClick.aspx?fileticket=4SFd9rpe%2b0I%3d&amp;tabid=73&amp;mid=406">Recheater</a> and
post a comment if you find any bugs or want to suggest an enhancement. 
</p>
        <img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=600c401c-a5dd-4bf8-b6c1-e1f2191237b8" />
      </body>
      <title>Recheater version 1.0a</title>
      <guid isPermaLink="false">http://weblog.ctrlalt313373.com/PermaLink,guid,600c401c-a5dd-4bf8-b6c1-e1f2191237b8.aspx</guid>
      <link>http://weblog.ctrlalt313373.com/2008/01/01/RecheaterVersion10a.aspx</link>
      <pubDate>Tue, 01 Jan 2008 17:09:57 GMT</pubDate>
      <description>&lt;p&gt;
Well lately I have been using &lt;a href="http://www.jetbrains.com/resharper/"&gt;Resharper&lt;/a&gt; from &lt;a href="http://www.jetbrains.com/"&gt;JetBrains&lt;/a&gt; which
is an amazing Visual Studio Add in that adds an extensive amount of new features and
shortcuts. It has greatly increased my productivity and if you're not using it then
you should at least download the 30 day trial and test it out. (Greg this means you.
Tell Matt I said he should buy it for you.) I especially like the file structure explorer
that allows me to organize functions and properties in a class by dragging them around
instead of needing to copy and paste them. This is very helpful when organizing your
classes into regions. Also, if you've ever had a giant solution where it begins to
be difficult to find files you'll appreciate the file search that allows you to start
typing a filename and get a filtered list of files. It definitely can be a bit overwhelming
with all the shortcuts it adds to Visual Studio so in order to make looking up the
shortcuts easier I created this basic VS2005 add in that displays the Resharper cheat
sheet on the screen. After installing the Recheater Add in you can display the cheat
sheet by hitting CTRL-ALT-SHIFT-H and close it down by hitting the ESC key. To change
the shortcut key simply modify the config file located under My Documents\Visual Studio
2005\Addins\RecheaterAddin. It's a pretty basic application, but feel free to download &lt;a href="http://www.ctrlalt313373.com/LinkClick.aspx?fileticket=4SFd9rpe%2b0I%3d&amp;amp;tabid=73&amp;amp;mid=406"&gt;Recheater&lt;/a&gt; and
post a comment if you find any bugs or want to suggest an enhancement. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=600c401c-a5dd-4bf8-b6c1-e1f2191237b8" /&gt;</description>
      <comments>http://weblog.ctrlalt313373.com/CommentView,guid,600c401c-a5dd-4bf8-b6c1-e1f2191237b8.aspx</comments>
      <category>Development</category>
      <category>Resharper</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://weblog.ctrlalt313373.com/Trackback.aspx?guid=5895c3e5-8465-4d3f-abdc-555fcfa4160d</trackback:ping>
      <pingback:server>http://weblog.ctrlalt313373.com/pingback.aspx</pingback:server>
      <pingback:target>http://weblog.ctrlalt313373.com/PermaLink,guid,5895c3e5-8465-4d3f-abdc-555fcfa4160d.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://weblog.ctrlalt313373.com/CommentView,guid,5895c3e5-8465-4d3f-abdc-555fcfa4160d.aspx</wfw:comment>
      <wfw:commentRss>http://weblog.ctrlalt313373.com/SyndicationService.asmx/GetEntryCommentsRss?guid=5895c3e5-8465-4d3f-abdc-555fcfa4160d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm my last <a href="http://weblog.ctrlalt313373.com/2007/12/27/CreatingARegExActivityForWindowsWorkflow.aspx">posting</a> I
walked through how to create a custom regex activity in Windows Workflow and I thought
a good next step would be to give a short example of how you would add validation
to this custom activity. In this particular instance we want to make the InputString
property and the RegExpression property required in order for the workflow designer
to consider the workflow that is being built a valid workflow. The first thing that
needs to be done is to add a class to the project called RegExValidator.cs. 
</p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/122907_0256_AddingValid1.png" alt="" />
        </p>
        <p>
        </p>
        <p>
The next thing that needs to be done to the new class is to add <span style="font-family:Courier New; font-size:10pt"><span style="color:blue">using</span> System.Workflow.ComponentModel.Compiler </span>to
the top of the class and make it inherit from ActivityValidator. The one function
that we need to override is the validate function. The validate function takes in
a ValidationManager and an object. The object is what we will be using as this is
the instance of our activity that we will be validating. The function returns a ValidationErrorCollection
which is simply a collection of error messages that we will send back after validating
the activity. In the override for this function we check that both the InputString
and the RegExpression properties are not null or empty. If they are we add a corresponding
error message to the collection. Because the error is associated with a property we
provide the property name as the last parameter in the constructor for the ValidationError
object so that the designer can associate the error message with the apporpriate property.<span style="font-family:Courier New; font-size:10pt"></span></p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">class</span>
            <span style="color:#2b91af">RegExValidator</span> : <span style="color:#2b91af">ActivityValidator </span></span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">override</span>
            <span style="color:#2b91af">ValidationErrorCollection</span> Validate(<span style="color:#2b91af">ValidationManager</span> manager, <span style="color:blue">object</span> obj) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:#2b91af">RegEx</span> myRegEx
= obj <span style="color:blue">as</span><span style="color:#2b91af">RegEx</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:#2b91af">ValidationErrorCollection</span> myErrors
= <span style="color:blue">new</span><span style="color:#2b91af">ValidationErrorCollection</span>(); </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span> (myRegEx
!= <span style="color:blue">null</span> &amp;&amp; myRegEx.Parent != <span style="color:blue">null</span>) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span> (myRegEx.InputString
== <span style="color:blue">null</span> || myRegEx.InputString.Equals(<span style="color:#2b91af">String</span>.Empty)) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> myErrors.Add(<span style="color:blue">new</span><span style="color:#2b91af">ValidationError</span>(<span style="color:#a31515">"InputString
is required."</span>, 101, <span style="color:blue">false</span>, <span style="color:#a31515">"InputString"</span>)); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span> (myRegEx.RegExpression
== <span style="color:blue">null</span> || myRegEx.RegExpression.Equals((<span style="color:#2b91af">String</span>.Empty))) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> myErrors.Add(<span style="color:blue">new</span><span style="color:#2b91af">ValidationError</span>(<span style="color:#a31515">"RegExpression
is required."</span>, 102, <span style="color:blue">false</span>, <span style="color:#a31515">"RegExpression"</span>)); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">return</span> myErrors; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
          </span>That is all we need
to do for the validator class. The last thing we need to do is associate our validator
with the activity. To do this we add the same using statement to our RegEx.cs activity
(<span style="font-family:Courier New; font-size:10pt"><span style="color:blue">using</span> System.Workflow.ComponentModel.Compiler</span>)
and we add an attribute to the top of the class. 
</p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> [<span style="color:#2b91af">ActivityValidator</span>(<span style="color:blue">typeof</span>(<span style="color:#2b91af">RegExValidator</span>))] </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">partial</span>
            <span style="color:blue">class</span>
            <span style="color:#2b91af">RegEx</span>: <span style="color:#2b91af">BaseActivity </span></span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> … </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> }</span>
        </p>
        <p>
That's it. If we now use the original sample workflow I created and blank out the
InputString and RegExpression properties we will get several indications that there
are errors. First in the designer it will be indicated directly on the activity. 
</p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/122907_0256_AddingValid2.png" alt="" />
        </p>
        <p>
In the properties window it will also indicate each individual property that has an
error. 
</p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/122907_0256_AddingValid3.png" alt="" />
        </p>
        <p>
Finally the build will error and the error messages will be provided in the error
window. 
</p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/122907_0256_AddingValid4.png" alt="" />
        </p>
        <p>
        </p>
        <p>
That's all I have to say about validation. Obviously the validation can be much more
complicated than just checking if the property has been provided, but this example
hopefully provides a basic idea of how to get things going. Feel free to post a comment
if you found this helpful and would like for me to dedicate more postings to the wonderful
world of workflow. Now I'm off to go find a life since it appears that I am blogging
on a Friday night. Unfortunately that's not something you can Google for!
</p>
        <img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=5895c3e5-8465-4d3f-abdc-555fcfa4160d" />
      </body>
      <title>Adding Validation to a Custom Workflow Activity</title>
      <guid isPermaLink="false">http://weblog.ctrlalt313373.com/PermaLink,guid,5895c3e5-8465-4d3f-abdc-555fcfa4160d.aspx</guid>
      <link>http://weblog.ctrlalt313373.com/2007/12/29/AddingValidationToACustomWorkflowActivity.aspx</link>
      <pubDate>Sat, 29 Dec 2007 02:54:49 GMT</pubDate>
      <description>&lt;p&gt;
I'm my last &lt;a href="http://weblog.ctrlalt313373.com/2007/12/27/CreatingARegExActivityForWindowsWorkflow.aspx"&gt;posting&lt;/a&gt; I
walked through how to create a custom regex activity in Windows Workflow and I thought
a good next step would be to give a short example of how you would add validation
to this custom activity. In this particular instance we want to make the InputString
property and the RegExpression property required in order for the workflow designer
to consider the workflow that is being built a valid workflow. The first thing that
needs to be done is to add a class to the project called RegExValidator.cs. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/122907_0256_AddingValid1.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
The next thing that needs to be done to the new class is to add &lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;using&lt;/span&gt; System.Workflow.ComponentModel.Compiler &lt;/span&gt;to
the top of the class and make it inherit from ActivityValidator. The one function
that we need to override is the validate function. The validate function takes in
a ValidationManager and an object. The object is what we will be using as this is
the instance of our activity that we will be validating. The function returns a ValidationErrorCollection
which is simply a collection of error messages that we will send back after validating
the activity. In the override for this function we check that both the InputString
and the RegExpression properties are not null or empty. If they are we add a corresponding
error message to the collection. Because the error is associated with a property we
provide the property name as the last parameter in the constructor for the ValidationError
object so that the designer can associate the error message with the apporpriate property.&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;RegExValidator&lt;/span&gt; : &lt;span style="color:#2b91af"&gt;ActivityValidator &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;override&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ValidationErrorCollection&lt;/span&gt; Validate(&lt;span style="color:#2b91af"&gt;ValidationManager&lt;/span&gt; manager, &lt;span style="color:blue"&gt;object&lt;/span&gt; obj) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:#2b91af"&gt;RegEx&lt;/span&gt; myRegEx
= obj &lt;span style="color:blue"&gt;as&lt;/span&gt; &lt;span style="color:#2b91af"&gt;RegEx&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:#2b91af"&gt;ValidationErrorCollection&lt;/span&gt; myErrors
= &lt;span style="color:blue"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ValidationErrorCollection&lt;/span&gt;(); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt; (myRegEx
!= &lt;span style="color:blue"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; myRegEx.Parent != &lt;span style="color:blue"&gt;null&lt;/span&gt;) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt; (myRegEx.InputString
== &lt;span style="color:blue"&gt;null&lt;/span&gt; || myRegEx.InputString.Equals(&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.Empty)) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; myErrors.Add(&lt;span style="color:blue"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ValidationError&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"InputString
is required."&lt;/span&gt;, 101, &lt;span style="color:blue"&gt;false&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"InputString"&lt;/span&gt;)); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt; (myRegEx.RegExpression
== &lt;span style="color:blue"&gt;null&lt;/span&gt; || myRegEx.RegExpression.Equals((&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.Empty))) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; myErrors.Add(&lt;span style="color:blue"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ValidationError&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"RegExpression
is required."&lt;/span&gt;, 102, &lt;span style="color:blue"&gt;false&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"RegExpression"&lt;/span&gt;)); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;return&lt;/span&gt; myErrors; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;/span&gt;That is all we need
to do for the validator class. The last thing we need to do is associate our validator
with the activity. To do this we add the same using statement to our RegEx.cs activity
(&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;using&lt;/span&gt; System.Workflow.ComponentModel.Compiler&lt;/span&gt;)
and we add an attribute to the top of the class. 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; [&lt;span style="color:#2b91af"&gt;ActivityValidator&lt;/span&gt;(&lt;span style="color:blue"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;RegExValidator&lt;/span&gt;))] &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;partial&lt;/span&gt; &lt;span style="color:blue"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;RegEx&lt;/span&gt;: &lt;span style="color:#2b91af"&gt;BaseActivity &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; … &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; }&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
That's it. If we now use the original sample workflow I created and blank out the
InputString and RegExpression properties we will get several indications that there
are errors. First in the designer it will be indicated directly on the activity. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/122907_0256_AddingValid2.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
In the properties window it will also indicate each individual property that has an
error. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/122907_0256_AddingValid3.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
Finally the build will error and the error messages will be provided in the error
window. 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/122907_0256_AddingValid4.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
That's all I have to say about validation. Obviously the validation can be much more
complicated than just checking if the property has been provided, but this example
hopefully provides a basic idea of how to get things going. Feel free to post a comment
if you found this helpful and would like for me to dedicate more postings to the wonderful
world of workflow. Now I'm off to go find a life since it appears that I am blogging
on a Friday night. Unfortunately that's not something you can Google for!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=5895c3e5-8465-4d3f-abdc-555fcfa4160d" /&gt;</description>
      <comments>http://weblog.ctrlalt313373.com/CommentView,guid,5895c3e5-8465-4d3f-abdc-555fcfa4160d.aspx</comments>
      <category>.Net 3.0</category>
      <category>Development</category>
      <category>Windows Workflow</category>
    </item>
    <item>
      <trackback:ping>http://weblog.ctrlalt313373.com/Trackback.aspx?guid=ff2cc65e-d0c0-42d4-a618-46c7263b21d5</trackback:ping>
      <pingback:server>http://weblog.ctrlalt313373.com/pingback.aspx</pingback:server>
      <pingback:target>http://weblog.ctrlalt313373.com/PermaLink,guid,ff2cc65e-d0c0-42d4-a618-46c7263b21d5.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://weblog.ctrlalt313373.com/CommentView,guid,ff2cc65e-d0c0-42d4-a618-46c7263b21d5.aspx</wfw:comment>
      <wfw:commentRss>http://weblog.ctrlalt313373.com/SyndicationService.asmx/GetEntryCommentsRss?guid=ff2cc65e-d0c0-42d4-a618-46c7263b21d5</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
While having lunch today at Old Chicago with <a href="http://www.developernotes.com">Nick</a> we
began discussing Windows Workflow a bit and I started to realize that even though
I have been pounding away on a project for six months that is highly dependent on
WF I have yet to write a single blog post on the topic. I found the need today to
work on an activity that simply applies a regular expression against a string and
returns the value that it finds. Since this is a fairly basic activity I thought I
would go ahead and blog about the process of creating it. 
</p>
        <p>
First off you need to create a new activity: 
</p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/122707_0341_CreatingaRe1.png" alt="" />
        </p>
        <p>
        </p>
        <p>
Visual Studio 2008 will create the skeleton of an activity for us that inherits from
SequenceActivity. For my purposes I need to have it inherit from Activity so I will
go ahead and change this. The next thing we need to do is to define a dependency property
for our input string. To do this we do the following 
</p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue"> #region</span> "Dependency
Properties" </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">static</span>
            <span style="color:#2b91af">DependencyProperty</span> InputStringProperty
= <span style="color:#2b91af">DependencyProperty</span>.Register(<span style="color:#a31515">"InputString"</span>, <span style="color:blue">typeof</span>(<span style="color:#2b91af">String</span>), <span style="color:blue">typeof</span>(<span style="color:#2b91af">RegEx</span>)); </span>
        </p>
        <p>
        </p>
        <p>
          <span style="color:blue; font-family:Courier New; font-size:10pt"> #endregion </span>
        </p>
        <p>
What we are doing here is registering a dependency property called InputStringProperty
that is bound to the property InputString (which we will be creating in a second),
the property of InputString is of type string and the owner of InputString (our activity)
is of type RegEx. Now we need to define our property InputString. 
</p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue"> #region</span> "Properties" </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">string</span> InputString </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">get</span> { <span style="color:blue">return</span> ((<span style="color:#2b91af">String</span>)(<span style="color:blue">base</span>.GetValue(<span style="color:#2b91af">RegEx</span>.InputStringProperty)));
} </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">set</span> { <span style="color:blue">base</span>.SetValue(<span style="color:#2b91af">RegEx</span>.InputStringProperty, <span style="color:blue">value</span>);
} </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
          <span style="color:blue; font-family:Courier New; font-size:10pt"> #endregion </span>
        </p>
        <p>
The layout of this property is fairly similar to what you should be useto, but instead
of getting and setting from a private member variable you instead set and get from
the dependency property. Piece of cake right? The next thing we are going to do is
define our output parameter the same way. The only thing that we are going to do differently
with this property is to put an attribute on it of readonly. This will prevent the
user from binding this property to something since the user should only be binding
the properties on other activities to this property. 
</p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">static</span>
            <span style="color:#2b91af">DependencyProperty</span> OutputStringProperty
= <span style="color:#2b91af">DependencyProperty</span>.Register(<span style="color:#a31515">"OutputString"</span>, <span style="color:blue">typeof</span>(<span style="color:#2b91af">String</span>), <span style="color:blue">typeof</span>(<span style="color:#2b91af">RegEx</span>)); </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> [<span style="color:#2b91af">ReadOnly</span>(<span style="color:blue">true</span>)] </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">string</span> OutputString </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">get</span> { <span style="color:blue">return</span> ((<span style="color:#2b91af">String</span>)(<span style="color:blue">base</span>.GetValue(<span style="color:#2b91af">RegEx</span>.OutputStringProperty)));
} </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">set</span> { <span style="color:blue">base</span>.SetValue(<span style="color:#2b91af">RegEx</span>.OutputStringProperty, <span style="color:blue">value</span>);
} </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> }</span>
        </p>
        <p style="margin-left: 54pt">
        </p>
        <p style="margin-left: 54pt">
        </p>
        <p>
Though we are not complete yet, if you build this activity and drop it onto a test
workflow you will see the following in your Visual Studio Properties Window. We have
a property call input string that is bindable and a property called OutputString that
is readonly. 
</p>
        <p style="margin-left: 54pt">
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/122707_0341_CreatingaRe2.png" alt="" />
        </p>
        <p>
        </p>
        <p>
The next things we need to do is to declare a property that will hold our regular
expression for the user of our activity to input. The will not be a dependency property,
but a standard property as it will not need the ability for binding. 
</p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">private</span>
            <span style="color:blue">string</span> _regexpression;</span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">string</span> RegExpression </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">get</span> { <span style="color:blue">return</span> _regexpression;
} </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">set</span> {
_regexpression = <span style="color:blue">value</span>;} </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
If you now drop this activity onto a test workflow you will see the following on the
properties window. 
</p>
        <p>
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/122707_0341_CreatingaRe3.png" alt="" />
        </p>
        <p>
        </p>
        <p>
We're almost done and all that is left to do is to implement the Execute method of
our activity which will actually evaluate our regular expression against the input
string. First off make sure you put <span style="font-family:Courier New; font-size:10pt"><span style="color:blue">using</span> System.Text.RegularExpressions </span>at
the top of the class as we will obviously be using the .Net RegEx features. Then we
just have the following function left. 
</p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">protected</span>
            <span style="color:blue">override</span>
            <span style="color:#2b91af">ActivityExecutionStatus</span> Execute(<span style="color:#2b91af">ActivityExecutionContext</span> executionContext) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:#2b91af">Regex</span> myRegEx
= <span style="color:blue">new</span><span style="color:#2b91af">Regex</span>(RegExpression, <span style="color:#2b91af">RegexOptions</span>.IgnoreCase); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> OutputString = myRegEx.Match(InputString).Value; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">return</span>
            <span style="color:#2b91af">ActivityExecutionStatus</span>.Closed; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
The Exceute function is the meat of the activity where our processing actually happens.
We first create a new RegEx object using our RegExpression property and in this case
we are passing the option to ignore case. We then evaluate the regular expression
and place the value into our OutputString property. Finally we return with a closed
status and that's it. Just to test it out I put together a basic workflow that consists
of my activity with the InputString property set to "my email address is testperson@test.com
and of course it isn't a real email" and the RegExpression property set to "\w+([-+.']\w+)<a href="mailto:*@\w+([-.]\w+)*\.\w+([-.]\w+)*">*@\w+([-.]\w+)*\.\w+([-.]\w+)*</a>"
which should pull out the email address. I then used a basic code activity to output
the email address to the console. 
</p>
        <p>
        </p>
        <p>
          <img src="http://weblog.ctrlalt313373.com/content/binary/122707_0341_CreatingaRe4.png" alt="" />
        </p>
        <p>
        </p>
        <p>
There you have it, a workflow activity that evaluates a regular expression against
a string. If an email address had not been found then a blank line would have been
written out to the console, but in our case we got <a href="mailto:testpersion@test.com">testpersion@test.com</a>.
Obviously in a more practical scenario you would not type the string directly into
the InputString property, but instead you would bind that property to the string property
on an activity earlier in the workflow, but you get the idea. That's it for now folks.
If you enjoyed this posting or found it helpful and would like to see me post more
on WF feel free to post a comment. 
</p>
        <img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=ff2cc65e-d0c0-42d4-a618-46c7263b21d5" />
      </body>
      <title>Creating a RegEx Activity for Windows Workflow</title>
      <guid isPermaLink="false">http://weblog.ctrlalt313373.com/PermaLink,guid,ff2cc65e-d0c0-42d4-a618-46c7263b21d5.aspx</guid>
      <link>http://weblog.ctrlalt313373.com/2007/12/27/CreatingARegExActivityForWindowsWorkflow.aspx</link>
      <pubDate>Thu, 27 Dec 2007 03:39:10 GMT</pubDate>
      <description>&lt;p&gt;
While having lunch today at Old Chicago with &lt;a href="http://www.developernotes.com"&gt;Nick&lt;/a&gt; we
began discussing Windows Workflow a bit and I started to realize that even though
I have been pounding away on a project for six months that is highly dependent on
WF I have yet to write a single blog post on the topic. I found the need today to
work on an activity that simply applies a regular expression against a string and
returns the value that it finds. Since this is a fairly basic activity I thought I
would go ahead and blog about the process of creating it. 
&lt;/p&gt;
&lt;p&gt;
First off you need to create a new activity: 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/122707_0341_CreatingaRe1.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Visual Studio 2008 will create the skeleton of an activity for us that inherits from
SequenceActivity. For my purposes I need to have it inherit from Activity so I will
go ahead and change this. The next thing we need to do is to define a dependency property
for our input string. To do this we do the following 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt; #region&lt;/span&gt; "Dependency
Properties" &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af"&gt;DependencyProperty&lt;/span&gt; InputStringProperty
= &lt;span style="color:#2b91af"&gt;DependencyProperty&lt;/span&gt;.Register(&lt;span style="color:#a31515"&gt;"InputString"&lt;/span&gt;, &lt;span style="color:blue"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;), &lt;span style="color:blue"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;RegEx&lt;/span&gt;)); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="color:blue; font-family:Courier New; font-size:10pt"&gt; #endregion &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
What we are doing here is registering a dependency property called InputStringProperty
that is bound to the property InputString (which we will be creating in a second),
the property of InputString is of type string and the owner of InputString (our activity)
is of type RegEx. Now we need to define our property InputString. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt; #region&lt;/span&gt; "Properties" &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;string&lt;/span&gt; InputString &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;get&lt;/span&gt; { &lt;span style="color:blue"&gt;return&lt;/span&gt; ((&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;)(&lt;span style="color:blue"&gt;base&lt;/span&gt;.GetValue(&lt;span style="color:#2b91af"&gt;RegEx&lt;/span&gt;.InputStringProperty)));
} &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;set&lt;/span&gt; { &lt;span style="color:blue"&gt;base&lt;/span&gt;.SetValue(&lt;span style="color:#2b91af"&gt;RegEx&lt;/span&gt;.InputStringProperty, &lt;span style="color:blue"&gt;value&lt;/span&gt;);
} &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="color:blue; font-family:Courier New; font-size:10pt"&gt; #endregion &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
The layout of this property is fairly similar to what you should be useto, but instead
of getting and setting from a private member variable you instead set and get from
the dependency property. Piece of cake right? The next thing we are going to do is
define our output parameter the same way. The only thing that we are going to do differently
with this property is to put an attribute on it of readonly. This will prevent the
user from binding this property to something since the user should only be binding
the properties on other activities to this property. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af"&gt;DependencyProperty&lt;/span&gt; OutputStringProperty
= &lt;span style="color:#2b91af"&gt;DependencyProperty&lt;/span&gt;.Register(&lt;span style="color:#a31515"&gt;"OutputString"&lt;/span&gt;, &lt;span style="color:blue"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;), &lt;span style="color:blue"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;RegEx&lt;/span&gt;)); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; [&lt;span style="color:#2b91af"&gt;ReadOnly&lt;/span&gt;(&lt;span style="color:blue"&gt;true&lt;/span&gt;)] &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;string&lt;/span&gt; OutputString &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;get&lt;/span&gt; { &lt;span style="color:blue"&gt;return&lt;/span&gt; ((&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;)(&lt;span style="color:blue"&gt;base&lt;/span&gt;.GetValue(&lt;span style="color:#2b91af"&gt;RegEx&lt;/span&gt;.OutputStringProperty)));
} &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;set&lt;/span&gt; { &lt;span style="color:blue"&gt;base&lt;/span&gt;.SetValue(&lt;span style="color:#2b91af"&gt;RegEx&lt;/span&gt;.OutputStringProperty, &lt;span style="color:blue"&gt;value&lt;/span&gt;);
} &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; }&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="margin-left: 54pt"&gt;
&lt;/p&gt;
&lt;p style="margin-left: 54pt"&gt;
&lt;/p&gt;
&lt;p&gt;
Though we are not complete yet, if you build this activity and drop it onto a test
workflow you will see the following in your Visual Studio Properties Window. We have
a property call input string that is bindable and a property called OutputString that
is readonly. 
&lt;/p&gt;
&lt;p style="margin-left: 54pt"&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/122707_0341_CreatingaRe2.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
The next things we need to do is to declare a property that will hold our regular
expression for the user of our activity to input. The will not be a dependency property,
but a standard property as it will not need the ability for binding. 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:blue"&gt;string&lt;/span&gt; _regexpression;&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;string&lt;/span&gt; RegExpression &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;get&lt;/span&gt; { &lt;span style="color:blue"&gt;return&lt;/span&gt; _regexpression;
} &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;set&lt;/span&gt; {
_regexpression = &lt;span style="color:blue"&gt;value&lt;/span&gt;;} &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
If you now drop this activity onto a test workflow you will see the following on the
properties window. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/122707_0341_CreatingaRe3.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
We're almost done and all that is left to do is to implement the Execute method of
our activity which will actually evaluate our regular expression against the input
string. First off make sure you put &lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;using&lt;/span&gt; System.Text.RegularExpressions &lt;/span&gt;at
the top of the class as we will obviously be using the .Net RegEx features. Then we
just have the following function left. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;protected&lt;/span&gt; &lt;span style="color:blue"&gt;override&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ActivityExecutionStatus&lt;/span&gt; Execute(&lt;span style="color:#2b91af"&gt;ActivityExecutionContext&lt;/span&gt; executionContext) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:#2b91af"&gt;Regex&lt;/span&gt; myRegEx
= &lt;span style="color:blue"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Regex&lt;/span&gt;(RegExpression, &lt;span style="color:#2b91af"&gt;RegexOptions&lt;/span&gt;.IgnoreCase); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; OutputString = myRegEx.Match(InputString).Value; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;return&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ActivityExecutionStatus&lt;/span&gt;.Closed; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
The Exceute function is the meat of the activity where our processing actually happens.
We first create a new RegEx object using our RegExpression property and in this case
we are passing the option to ignore case. We then evaluate the regular expression
and place the value into our OutputString property. Finally we return with a closed
status and that's it. Just to test it out I put together a basic workflow that consists
of my activity with the InputString property set to "my email address is testperson@test.com
and of course it isn't a real email" and the RegExpression property set to "\w+([-+.']\w+)&lt;a href="mailto:*@\w+([-.]\w+)*\.\w+([-.]\w+)*"&gt;*@\w+([-.]\w+)*\.\w+([-.]\w+)*&lt;/a&gt;"
which should pull out the email address. I then used a basic code activity to output
the email address to the console. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://weblog.ctrlalt313373.com/content/binary/122707_0341_CreatingaRe4.png" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
There you have it, a workflow activity that evaluates a regular expression against
a string. If an email address had not been found then a blank line would have been
written out to the console, but in our case we got &lt;a href="mailto:testpersion@test.com"&gt;testpersion@test.com&lt;/a&gt;.
Obviously in a more practical scenario you would not type the string directly into
the InputString property, but instead you would bind that property to the string property
on an activity earlier in the workflow, but you get the idea. That's it for now folks.
If you enjoyed this posting or found it helpful and would like to see me post more
on WF feel free to post a comment. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=ff2cc65e-d0c0-42d4-a618-46c7263b21d5" /&gt;</description>
      <comments>http://weblog.ctrlalt313373.com/CommentView,guid,ff2cc65e-d0c0-42d4-a618-46c7263b21d5.aspx</comments>
      <category>.Net 3.0</category>
      <category>Development</category>
      <category>Windows Workflow</category>
    </item>
    <item>
      <trackback:ping>http://weblog.ctrlalt313373.com/Trackback.aspx?guid=2a23d68a-6a35-4394-9a19-4cd80d64d900</trackback:ping>
      <pingback:server>http://weblog.ctrlalt313373.com/pingback.aspx</pingback:server>
      <pingback:target>http://weblog.ctrlalt313373.com/PermaLink,guid,2a23d68a-6a35-4394-9a19-4cd80d64d900.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://weblog.ctrlalt313373.com/CommentView,guid,2a23d68a-6a35-4394-9a19-4cd80d64d900.aspx</wfw:comment>
      <wfw:commentRss>http://weblog.ctrlalt313373.com/SyndicationService.asmx/GetEntryCommentsRss?guid=2a23d68a-6a35-4394-9a19-4cd80d64d900</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The other day I ran into the need to access a nested property on an object with the
actual name and path to the property stored in a string variable. For example I had
a mail object and wanted to access "From.DisplayName" which was stored in a string.
If I was access just the from I could have used something like this: 
</p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">using</span> System.Reflection;</span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:#2b91af">PropertyInfo</span>[]
pi = myObject.GetType().GetProperties(); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">foreach</span> (<span style="color:#2b91af">PropertyInfo</span> item <span style="color:blue">in</span> pi) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span> (item.Name
= <span style="color:#a31515">"From"</span>) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">object</span> o
= item.GetValue(myObject, <span style="color:blue">null</span>); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
In this example myObject is the mail object and we first get the type of it, and then
get an array of the properties for that type. Finally we find the From property and
get the value for that property on our object. 
</p>
        <p>
Unfortunately this doesn't work for nested properties and I could not find a built
in way to do it so I built a recursive function to handle getting the property for
me and returning it. I then packaged it into a handy .Net 3.5 extension method. Let
me know if you know of a built in method to get a nested property, otherwise feel
free to using the extension method I put together, though it probably needs a bit
of refactoring before you put it into production. 
</p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">namespace</span> Common.ExtensionMethods </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">{ </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">static</span>
            <span style="color:blue">class</span>
            <span style="color:#2b91af">TypeExtensionMethods </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">public</span>
            <span style="color:blue">static</span>
            <span style="color:blue">object</span> GetNestedProperty(<span style="color:blue">this</span><span style="color:#2b91af">Type</span> t, <span style="color:#2b91af">Object</span> o, <span style="color:#2b91af">String</span> Property) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">object</span> myObject
= <span style="color:blue">null</span>; </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:#2b91af">PropertyInfo</span>[]
pi = t.GetProperties(); </span>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span> (Property.IndexOf(<span style="color:#a31515">"."</span>)
!= -1) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">foreach</span> (<span style="color:#2b91af">PropertyInfo</span> item <span style="color:blue">in</span> pi) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span> (item.Name
== Property.Substring(0, Property.IndexOf(<span style="color:#a31515">"."</span>))) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">object</span> tmpObj
= item.GetValue(o, <span style="color:blue">null</span>); </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> myObject = tmpObj.GetType().GetNestedProperty(tmpObj,
Property.Substring(Property.IndexOf(<span style="color:#a31515">"."</span>) + 1)); </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">else </span>
          </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">foreach</span> (<span style="color:#2b91af">PropertyInfo</span> item <span style="color:blue">in</span> pi) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">if</span> (item.Name
== Property) </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> { </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> myObject = item.GetValue(o, <span style="color:blue">null</span>); </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">
            <span style="color:blue">return</span> myObject; </span>
        </p>
        <p>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt"> } </span>
        </p>
        <p>
          <span style="font-family:Courier New; font-size:10pt">} </span>
        </p>
        <img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=2a23d68a-6a35-4394-9a19-4cd80d64d900" />
      </body>
      <title>Accessing a Nested Property via a String</title>
      <guid isPermaLink="false">http://weblog.ctrlalt313373.com/PermaLink,guid,2a23d68a-6a35-4394-9a19-4cd80d64d900.aspx</guid>
      <link>http://weblog.ctrlalt313373.com/2007/11/25/AccessingANestedPropertyViaAString.aspx</link>
      <pubDate>Sun, 25 Nov 2007 16:03:26 GMT</pubDate>
      <description>&lt;p&gt;
The other day I ran into the need to access a nested property on an object with the
actual name and path to the property stored in a string variable. For example I had
a mail object and wanted to access "From.DisplayName" which was stored in a string.
If I was access just the from I could have used something like this: 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;using&lt;/span&gt; System.Reflection;&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:#2b91af"&gt;PropertyInfo&lt;/span&gt;[]
pi = myObject.GetType().GetProperties(); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;foreach&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;PropertyInfo&lt;/span&gt; item &lt;span style="color:blue"&gt;in&lt;/span&gt; pi) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt; (item.Name
= &lt;span style="color:#a31515"&gt;"From"&lt;/span&gt;) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;object&lt;/span&gt; o
= item.GetValue(myObject, &lt;span style="color:blue"&gt;null&lt;/span&gt;); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
In this example myObject is the mail object and we first get the type of it, and then
get an array of the properties for that type. Finally we find the From property and
get the value for that property on our object. 
&lt;/p&gt;
&lt;p&gt;
Unfortunately this doesn't work for nested properties and I could not find a built
in way to do it so I built a recursive function to handle getting the property for
me and returning it. I then packaged it into a handy .Net 3.5 extension method. Let
me know if you know of a built in method to get a nested property, otherwise feel
free to using the extension method I put together, though it probably needs a bit
of refactoring before you put it into production. 
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;namespace&lt;/span&gt; Common.ExtensionMethods &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;{ &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;static&lt;/span&gt; &lt;span style="color:blue"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;TypeExtensionMethods &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;static&lt;/span&gt; &lt;span style="color:blue"&gt;object&lt;/span&gt; GetNestedProperty(&lt;span style="color:blue"&gt;this&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Type&lt;/span&gt; t, &lt;span style="color:#2b91af"&gt;Object&lt;/span&gt; o, &lt;span style="color:#2b91af"&gt;String&lt;/span&gt; Property) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;object&lt;/span&gt; myObject
= &lt;span style="color:blue"&gt;null&lt;/span&gt;; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:#2b91af"&gt;PropertyInfo&lt;/span&gt;[]
pi = t.GetProperties(); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt; (Property.IndexOf(&lt;span style="color:#a31515"&gt;"."&lt;/span&gt;)
!= -1) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;foreach&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;PropertyInfo&lt;/span&gt; item &lt;span style="color:blue"&gt;in&lt;/span&gt; pi) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt; (item.Name
== Property.Substring(0, Property.IndexOf(&lt;span style="color:#a31515"&gt;"."&lt;/span&gt;))) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;object&lt;/span&gt; tmpObj
= item.GetValue(o, &lt;span style="color:blue"&gt;null&lt;/span&gt;); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; myObject = tmpObj.GetType().GetNestedProperty(tmpObj,
Property.Substring(Property.IndexOf(&lt;span style="color:#a31515"&gt;"."&lt;/span&gt;) + 1)); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;else &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;foreach&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;PropertyInfo&lt;/span&gt; item &lt;span style="color:blue"&gt;in&lt;/span&gt; pi) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;if&lt;/span&gt; (item.Name
== Property) &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; { &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; myObject = item.GetValue(o, &lt;span style="color:blue"&gt;null&lt;/span&gt;); &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; &lt;span style="color:blue"&gt;return&lt;/span&gt; myObject; &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt; } &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family:Courier New; font-size:10pt"&gt;} &lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=2a23d68a-6a35-4394-9a19-4cd80d64d900" /&gt;</description>
      <comments>http://weblog.ctrlalt313373.com/CommentView,guid,2a23d68a-6a35-4394-9a19-4cd80d64d900.aspx</comments>
      <category>Development</category>
      <category>Extension Methods</category>
    </item>
    <item>
      <trackback:ping>http://weblog.ctrlalt313373.com/Trackback.aspx?guid=f8f23d92-b43f-4050-b275-0ea3ff7fbd2b</trackback:ping>
      <pingback:server>http://weblog.ctrlalt313373.com/pingback.aspx</pingback:server>
      <pingback:target>http://weblog.ctrlalt313373.com/PermaLink,guid,f8f23d92-b43f-4050-b275-0ea3ff7fbd2b.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://weblog.ctrlalt313373.com/CommentView,guid,f8f23d92-b43f-4050-b275-0ea3ff7fbd2b.aspx</wfw:comment>
      <wfw:commentRss>http://weblog.ctrlalt313373.com/SyndicationService.asmx/GetEntryCommentsRss?guid=f8f23d92-b43f-4050-b275-0ea3ff7fbd2b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I originally thought of this idea while at Professional Edge. We had a client that
wanted to build a portal and resell the functionality it provided to other companies.
The main functionality and content for the site would be the same for each customer,
but styles, images, and logos would change based on each company allowing the company
to portray the website as their own. Professional Edge closed before the project was
signed off on so I never got the chance to tackle a solution, but every once in awhile
the concepts pops back into my head. I am sure this is a fairly common scenario and
most likely what I have done here has been done plenty of times before, but I thought
I would attempt to put together a proof of concept. My initial plan was to dynamically
generate the App_Themes data based on information from the database. Using this method
the developer would build the site with the look and feel defined via css tags and
skin ids. The end corporate user would then have a user interface to define their
custom styles and images that applied to each css tag and skin id. If the user did
not define a tag then the website would simple use a default theme that the developer
defined. 
</p>
        <p>
To do all this I have utilized the functionality of virtual path providers. A virtual
path provider allows you to essentially take over when ASP.NET is looking for the
file to server to the user. In my particular case it is for .css and .skin files,
so that whenever a request comes in for one of these files it is instead dynamically
built based on data from the database. Originally I had planned to associate a particular
theme name with each portal's customizations. For example on the pre-init the theme
would be dynamically set based on some type of user information, either a login account,
or possibly the web address used to access the site. Basically any type of information
that establishes the unique portal that the visitor is attempting to reach. Unfortunately
this plan won't work. Apparently ASP.NET requires the actual physical files for a
theme to exist or else it will throw an error. This was a bit of a disappointment
to me as I had hoped to parse the theme name in the virtual path provider to know
what dynamic data to load. Since the path is the only data passed into the virtual
path provider it is the easiest and cleanest way to know what data to load. If the
file trying to be loaded is ThemeABC.css I could load the styles for portal ABC and
if the file trying to be loaded was ThemeXYZ.css then I could have loaded the styles
for portal XYZ. 
</p>
        <p>
Even though this method didn't work I was able to development another method that
does. I have created the file structure for the Default theme with dummy files, including
Default.css and Default.skin. Every portal will essentially be using this theme as
far as ASP.NET is concerned, but when a request comes in for Default.css or Default.skin
I pass back a dynamically generated file. The decision for what styles and ids need
to be loaded is based on a cookie that is set in the pre-init. This cookie is then
read in the in the Open function of the virtual file class for the virtual path provider
and based on what the cookie says a decision is made as to what styles are handed
back to the client. 
</p>
        <p>
In the attached sample code there are two different themes that can be accessed, blue
and red. Setting the cookie is handled in the Default.aspx's OnPreInit. Since this
is a proof of concept the actually string is hard coded, but it could just as easily
read the address that the request came in on, a user login, or user setting. Then
in the virtual path provider I handle any of the requests that come in for APP_THEME/DEFAULT/.
Finally in the virtual file class I read the theme name from the cookie and hand back
the proper page. Since this is a proof of concept I have simply hardcoded a few values
to hand back, but you could easily query the database and hand back a much more dynamically
generated file. 
</p>
        <p>
At this point hopefully you can see the numerous possibilities this allows for. If
all the ok buttons on the entire site are defined with a skin id of btnOk then you
could allow the user to upload the image they want for their ok buttons and instantly
all the ok buttons on the site reflect what the user has defined. If you consistently
use your css tags within you site then the user could easily define custom colors,
fonts, etc. for each one. This would allow the user to very easily customize the site
to the look and feel that represents their company without having a developer make
any changes. 
</p>
        <p>
Feel free to check out the sample code at the link below and make any comments or
suggestions. Since it is just a proof of concept it is a little rough and not that
elegant, but it displays the point. 
</p>
        <p>
          <a href="http://www.ctrlalt313373.com/LinkClick.aspx?fileticket=%2flXjUSp%2f%2bCI%3d&amp;tabid=65&amp;mid=390">Download
the source code to the proof of concept. (VS2008 required)</a>
        </p>
        <p>
        </p>
        <p>
        </p>
        <img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=f8f23d92-b43f-4050-b275-0ea3ff7fbd2b" />
      </body>
      <title>Dynamically Generating CSS and Skin Files for Custom User Experience</title>
      <guid isPermaLink="false">http://weblog.ctrlalt313373.com/PermaLink,guid,f8f23d92-b43f-4050-b275-0ea3ff7fbd2b.aspx</guid>
      <link>http://weblog.ctrlalt313373.com/2007/10/29/DynamicallyGeneratingCSSAndSkinFilesForCustomUserExperience.aspx</link>
      <pubDate>Mon, 29 Oct 2007 01:03:34 GMT</pubDate>
      <description>&lt;p&gt;
I originally thought of this idea while at Professional Edge. We had a client that
wanted to build a portal and resell the functionality it provided to other companies.
The main functionality and content for the site would be the same for each customer,
but styles, images, and logos would change based on each company allowing the company
to portray the website as their own. Professional Edge closed before the project was
signed off on so I never got the chance to tackle a solution, but every once in awhile
the concepts pops back into my head. I am sure this is a fairly common scenario and
most likely what I have done here has been done plenty of times before, but I thought
I would attempt to put together a proof of concept. My initial plan was to dynamically
generate the App_Themes data based on information from the database. Using this method
the developer would build the site with the look and feel defined via css tags and
skin ids. The end corporate user would then have a user interface to define their
custom styles and images that applied to each css tag and skin id. If the user did
not define a tag then the website would simple use a default theme that the developer
defined. 
&lt;/p&gt;
&lt;p&gt;
To do all this I have utilized the functionality of virtual path providers. A virtual
path provider allows you to essentially take over when ASP.NET is looking for the
file to server to the user. In my particular case it is for .css and .skin files,
so that whenever a request comes in for one of these files it is instead dynamically
built based on data from the database. Originally I had planned to associate a particular
theme name with each portal's customizations. For example on the pre-init the theme
would be dynamically set based on some type of user information, either a login account,
or possibly the web address used to access the site. Basically any type of information
that establishes the unique portal that the visitor is attempting to reach. Unfortunately
this plan won't work. Apparently ASP.NET requires the actual physical files for a
theme to exist or else it will throw an error. This was a bit of a disappointment
to me as I had hoped to parse the theme name in the virtual path provider to know
what dynamic data to load. Since the path is the only data passed into the virtual
path provider it is the easiest and cleanest way to know what data to load. If the
file trying to be loaded is ThemeABC.css I could load the styles for portal ABC and
if the file trying to be loaded was ThemeXYZ.css then I could have loaded the styles
for portal XYZ. 
&lt;/p&gt;
&lt;p&gt;
Even though this method didn't work I was able to development another method that
does. I have created the file structure for the Default theme with dummy files, including
Default.css and Default.skin. Every portal will essentially be using this theme as
far as ASP.NET is concerned, but when a request comes in for Default.css or Default.skin
I pass back a dynamically generated file. The decision for what styles and ids need
to be loaded is based on a cookie that is set in the pre-init. This cookie is then
read in the in the Open function of the virtual file class for the virtual path provider
and based on what the cookie says a decision is made as to what styles are handed
back to the client. 
&lt;/p&gt;
&lt;p&gt;
In the attached sample code there are two different themes that can be accessed, blue
and red. Setting the cookie is handled in the Default.aspx's OnPreInit. Since this
is a proof of concept the actually string is hard coded, but it could just as easily
read the address that the request came in on, a user login, or user setting. Then
in the virtual path provider I handle any of the requests that come in for APP_THEME/DEFAULT/.
Finally in the virtual file class I read the theme name from the cookie and hand back
the proper page. Since this is a proof of concept I have simply hardcoded a few values
to hand back, but you could easily query the database and hand back a much more dynamically
generated file. 
&lt;/p&gt;
&lt;p&gt;
At this point hopefully you can see the numerous possibilities this allows for. If
all the ok buttons on the entire site are defined with a skin id of btnOk then you
could allow the user to upload the image they want for their ok buttons and instantly
all the ok buttons on the site reflect what the user has defined. If you consistently
use your css tags within you site then the user could easily define custom colors,
fonts, etc. for each one. This would allow the user to very easily customize the site
to the look and feel that represents their company without having a developer make
any changes. 
&lt;/p&gt;
&lt;p&gt;
Feel free to check out the sample code at the link below and make any comments or
suggestions. Since it is just a proof of concept it is a little rough and not that
elegant, but it displays the point. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.ctrlalt313373.com/LinkClick.aspx?fileticket=%2flXjUSp%2f%2bCI%3d&amp;amp;tabid=65&amp;amp;mid=390"&gt;Download
the source code to the proof of concept. (VS2008 required)&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://weblog.ctrlalt313373.com/aggbug.ashx?id=f8f23d92-b43f-4050-b275-0ea3ff7fbd2b" /&gt;</description>
      <comments>http://weblog.ctrlalt313373.com/CommentView,guid,f8f23d92-b43f-4050-b275-0ea3ff7fbd2b.aspx</comments>
      <category>ASP.NET</category>
      <category>Development</category>
    </item>
  </channel>
</rss>