<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" 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:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
    <channel>
        <title>Nimble Coder</title>
        <link>http://nimblecoder.com/blog/Default.aspx</link>
        <description>Adventures in Nimble Coding</description>
        <language>en-US</language>
        <copyright>Ryan Van Slooten</copyright>
        <generator>Subtext Version 2.1.1.1</generator>
        <image>
            <title>Nimble Coder</title>
            <url>http://nimblecoder.com/blog/images/RSS2Image.gif</url>
            <link>http://nimblecoder.com/blog/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/NimbleCoder" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
            <title>Using a delegate and Custom Appender with log4net to display live log text</title>
            <category>C#</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/zrWB5Lg38LU/using-a-delegate-and-custom-appender-with-log4net-to-display.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/Displayinglivelogtextinapplicationusingl_C7AE/log4netAppender.png" rel="lightbox"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" title="log4netAppender sample" alt="log4netAppender sample" align="right" src="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/Displayinglivelogtextinapplicationusingl_C7AE/log4netAppender_thumb.png" width="240" height="180" /&gt;&lt;/a&gt; Recently I needed to display the text that was sent to log4net in a TextBox in a Form. It turns out this is very easy to do using a custom appender and the AppenderSkeleton. The custom appender uses a delegate to allow the host program to define a callback function to handle the log text as necessary.&lt;/p&gt; &lt;h4&gt;1. Create a new custom appender class&lt;/h4&gt; &lt;p&gt;I named my appender DelegateAppender because it needed to use a delegate to pass the text to the Form.&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color: navy"&gt;using &lt;/span&gt;&lt;span style="color: maroon"&gt;log4net&lt;/span&gt;.&lt;span style="color: maroon"&gt;Core&lt;/span&gt;;

&lt;span style="color: navy"&gt;namespace &lt;/span&gt;&lt;span style="color: maroon"&gt;log4net&lt;/span&gt;.&lt;span style="color: maroon"&gt;Appender
&lt;/span&gt;{
    &lt;span style="color: navy"&gt;public delegate void &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LogTextAppend&lt;/span&gt;(&lt;span style="color: navy"&gt;string &lt;/span&gt;&lt;span style="color: maroon"&gt;text&lt;/span&gt;);

    &lt;span style="color: navy"&gt;public class &lt;/span&gt;&lt;span style="color: #a65300"&gt;DelegateAppender &lt;/span&gt;: &lt;span style="color: maroon"&gt;log4net&lt;/span&gt;.&lt;span style="color: maroon"&gt;Appender&lt;/span&gt;.&lt;span style="color: #a65300"&gt;AppenderSkeleton
    &lt;/span&gt;{
        &lt;span style="color: navy"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LogTextAppend &lt;/span&gt;&lt;span style="color: maroon"&gt;logTextAppend&lt;/span&gt;;

        &lt;span style="color: navy"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LogTextAppend &lt;/span&gt;&lt;span style="color: maroon"&gt;LogTextMethod
        &lt;/span&gt;{
            &lt;span style="color: navy"&gt;get &lt;/span&gt;{ &lt;span style="color: navy"&gt;return &lt;/span&gt;&lt;span style="color: maroon"&gt;logTextAppend&lt;/span&gt;; }
            &lt;span style="color: navy"&gt;set &lt;/span&gt;{ &lt;span style="color: maroon"&gt;logTextAppend &lt;/span&gt;= &lt;span style="color: navy"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: navy"&gt;public &lt;/span&gt;&lt;span style="color: maroon"&gt;DelegateAppender&lt;/span&gt;()
        {
            &lt;span style="color: maroon"&gt;logTextAppend &lt;/span&gt;= &lt;span style="color: maroon"&gt;EmptyAppend&lt;/span&gt;;
        }

        &lt;span style="color: navy"&gt;private void &lt;/span&gt;&lt;span style="color: maroon"&gt;EmptyAppend&lt;/span&gt;(&lt;span style="color: navy"&gt;string &lt;/span&gt;&lt;span style="color: maroon"&gt;text&lt;/span&gt;)
        {
            &lt;span style="color: green"&gt;// Do nothing
        &lt;/span&gt;}

        &lt;span style="color: navy"&gt;protected override void &lt;/span&gt;&lt;span style="color: maroon"&gt;Append&lt;/span&gt;(&lt;span style="color: #a65300"&gt;LoggingEvent &lt;/span&gt;&lt;span style="color: maroon"&gt;loggingEvent&lt;/span&gt;)
        {
            &lt;span style="color: navy"&gt;if &lt;/span&gt;(&lt;span style="color: maroon"&gt;logTextAppend &lt;/span&gt;!= &lt;span style="color: navy"&gt;null&lt;/span&gt;)
                &lt;span style="color: maroon"&gt;logTextAppend&lt;/span&gt;(&lt;span style="color: maroon"&gt;RenderLoggingEvent&lt;/span&gt;(&lt;span style="color: maroon"&gt;loggingEvent&lt;/span&gt;));
        }
    }
}
&lt;/pre&gt;
&lt;h4&gt;2. Create and assign the delegate to the appender&lt;/h4&gt;
&lt;p&gt;As far as I could tell, there was no easy way to specify the delegate to use in the configuration of the DelegateAppender. Therefore I added a simple method to assign the delegate in the Form to the DelegateAppender.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: navy"&gt;public void &lt;/span&gt;&lt;span style="color: maroon"&gt;AddStatus&lt;/span&gt;(&lt;span style="color: navy"&gt;string &lt;/span&gt;&lt;span style="color: maroon"&gt;message&lt;/span&gt;)
{
    &lt;span style="color: maroon"&gt;textBoxStatus&lt;/span&gt;.&lt;span style="color: maroon"&gt;AppendText&lt;/span&gt;(&lt;span style="color: maroon"&gt;message&lt;/span&gt;);
}

&lt;span style="color: navy"&gt;private void &lt;/span&gt;&lt;span style="color: maroon"&gt;InitializeLogging&lt;/span&gt;()
{
    &lt;span style="color: navy"&gt;bool &lt;/span&gt;&lt;span style="color: maroon"&gt;initialized &lt;/span&gt;= &lt;span style="color: navy"&gt;false&lt;/span&gt;;

    &lt;span style="color: navy"&gt;if &lt;/span&gt;(!&lt;span style="color: maroon"&gt;log&lt;/span&gt;.&lt;span style="color: maroon"&gt;Logger&lt;/span&gt;.&lt;span style="color: maroon"&gt;Repository&lt;/span&gt;.&lt;span style="color: maroon"&gt;Configured&lt;/span&gt;)
    {
        &lt;span style="color: maroon"&gt;log4net&lt;/span&gt;.&lt;span style="color: maroon"&gt;Config&lt;/span&gt;.&lt;span style="color: #a65300"&gt;XmlConfigurator&lt;/span&gt;.&lt;span style="color: maroon"&gt;Configure&lt;/span&gt;();
        &lt;span style="color: maroon"&gt;textBoxStatus&lt;/span&gt;.&lt;span style="color: maroon"&gt;AppendText&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"WARNING: log4net not automatically configured. "&lt;/span&gt; +
            &lt;span style="background: #ffffe6"&gt;"Check AssemblyInfo.cs for - "&lt;/span&gt; +
            &lt;span style="background: #ffffe6"&gt;"[assembly: log4net.Config.XmlConfigurator(Watch=true)]\r\n"&lt;/span&gt;);
    }

    &lt;span style="color: navy"&gt;foreach &lt;/span&gt;(&lt;span style="color: maroon"&gt;log4net&lt;/span&gt;.&lt;span style="color: maroon"&gt;Appender&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;IAppender &lt;/span&gt;&lt;span style="color: maroon"&gt;appender &lt;/span&gt;&lt;span style="color: navy"&gt;in &lt;/span&gt;&lt;span style="color: maroon"&gt;log&lt;/span&gt;.&lt;span style="color: maroon"&gt;Logger&lt;/span&gt;.&lt;span style="color: maroon"&gt;Repository&lt;/span&gt;.&lt;span style="color: maroon"&gt;GetAppenders&lt;/span&gt;())
    {
        &lt;span style="color: navy"&gt;if &lt;/span&gt;(&lt;span style="color: maroon"&gt;appender&lt;/span&gt;.&lt;span style="color: maroon"&gt;GetType&lt;/span&gt;() == &lt;span style="color: navy"&gt;typeof&lt;/span&gt;(&lt;span style="color: maroon"&gt;log4net&lt;/span&gt;.&lt;span style="color: maroon"&gt;Appender&lt;/span&gt;.&lt;span style="color: #a65300"&gt;DelegateAppender&lt;/span&gt;))
        {
            &lt;span style="color: maroon"&gt;log4net&lt;/span&gt;.&lt;span style="color: maroon"&gt;Appender&lt;/span&gt;.&lt;span style="color: #a65300"&gt;DelegateAppender &lt;/span&gt;&lt;span style="color: maroon"&gt;delegateAppender &lt;/span&gt;= (&lt;span style="color: maroon"&gt;log4net&lt;/span&gt;.&lt;span style="color: maroon"&gt;Appender&lt;/span&gt;.&lt;span style="color: #a65300"&gt;DelegateAppender&lt;/span&gt;) &lt;span style="color: maroon"&gt;appender&lt;/span&gt;;
            &lt;span style="color: green"&gt;// .NET 2.0+
            &lt;/span&gt;&lt;span style="color: maroon"&gt;delegateAppender&lt;/span&gt;.&lt;span style="color: maroon"&gt;LogTextMethod &lt;/span&gt;= &lt;span style="color: navy"&gt;this&lt;/span&gt;.&lt;span style="color: maroon"&gt;AddStatus&lt;/span&gt;;
            &lt;span style="color: green"&gt;// .NET 1.1
            //delegateAppender.LogTextMethod = new log4net.Appender.LogTextAppend(this.AddStatus);
            &lt;/span&gt;&lt;span style="color: maroon"&gt;initialized &lt;/span&gt;= &lt;span style="color: navy"&gt;true&lt;/span&gt;;
        }
    }

    &lt;span style="color: navy"&gt;if &lt;/span&gt;(!&lt;span style="color: maroon"&gt;initialized&lt;/span&gt;)
    {
        &lt;span style="color: maroon"&gt;textBoxStatus&lt;/span&gt;.&lt;span style="color: maroon"&gt;AppendText&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"ERROR: Unable to add DelegateAppender to logging!\r\n"&lt;/span&gt;);
    }
}
&lt;/pre&gt;
&lt;h4&gt;3. Add the log4net configuration to app.config and AssemblyInfo.cs&lt;/h4&gt;
&lt;p&gt;The code for AssemblyInfo.cs just tells log4net to configure itself and also watch for changes.&lt;/p&gt;
&lt;pre class="code"&gt;[&lt;span style="color: navy"&gt;assembly&lt;/span&gt;: &lt;span style="color: maroon"&gt;log4net&lt;/span&gt;.&lt;span style="color: maroon"&gt;Config&lt;/span&gt;.&lt;span style="color: #a65300"&gt;XmlConfigurator&lt;/span&gt;(&lt;span style="color: maroon"&gt;Watch &lt;/span&gt;= &lt;span style="color: navy"&gt;true&lt;/span&gt;)]
&lt;/pre&gt;

&lt;p&gt;The app.config is as follows:  &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515"&gt;xml &lt;/span&gt;&lt;span style="color: red"&gt;version&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: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;" &lt;span style="color: blue"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configSections&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;section
   &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;log4net&lt;/span&gt;"
   &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;log4net.Config.Log4NetConfigurationSectionHandler, log4net&lt;/span&gt;"
  &lt;span style="color: blue"&gt;/&amp;gt;
 &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configSections&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;log4net&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;logger &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;log4netAppender.LogTestForm&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;level &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;ALL&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;logger&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;root&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;level &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;ALL&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;appender-ref &lt;/span&gt;&lt;span style="color: red"&gt;ref&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;DelegateAppender&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;root&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;appender
    &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;DelegateAppender&lt;/span&gt;"
    &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;log4net.Appender.DelegateAppender&lt;/span&gt;" &lt;span style="color: blue"&gt;&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;layout &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;log4net.Layout.PatternLayout&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;param
     &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;ConversionPattern&lt;/span&gt;"
     &lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;%m%n&lt;/span&gt;"
    &lt;span style="color: blue"&gt;/&amp;gt;
   &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;layout&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;appender&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
 &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;log4net&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;And there is a simple example of how to create a custom appender with log4net and hook it into an application.&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:96ab4fb1-d58f-447e-b5a9-214dd4b0e2f7" class="wlWriterEditableSmartContent"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/C%23" rel="tag"&gt;C#&lt;/a&gt;, &lt;a href="http://technorati.com/tags/log4net" rel="tag"&gt;log4net&lt;/a&gt;&lt;/div&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/76.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=zrWB5Lg38LU:yAQAAZyckSQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=zrWB5Lg38LU:yAQAAZyckSQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=zrWB5Lg38LU:yAQAAZyckSQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=zrWB5Lg38LU:yAQAAZyckSQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=zrWB5Lg38LU:yAQAAZyckSQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2009/01/30/using-a-delegate-and-custom-appender-with-log4net-to-display.aspx</guid>
            <pubDate>Fri, 30 Jan 2009 18:42:19 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/76.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2009/01/30/using-a-delegate-and-custom-appender-with-log4net-to-display.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/76.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/76.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2009/01/30/using-a-delegate-and-custom-appender-with-log4net-to-display.aspx</feedburner:origLink></item>
        <item>
            <title>Spinning Wait Symbol in Silverlight, Part4</title>
            <category>C#</category>
            <category>SilverLight</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/CycLGMvdFJ8/spinning-wait-symbol-in-silverlight-part4.aspx</link>
            <description>&lt;div&gt;&lt;a href="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/SpinningWaitSymbolinSilverlightPart4_9F71/SpinningCursor4TestPage.png"&gt;&lt;img height="178" alt="SpinningCursor4-TestPage" src="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/SpinningWaitSymbolinSilverlightPart4_9F71/SpinningCursor4TestPage_thumb.png" width="240" align="right" /&gt;&lt;/a&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;a title="SpinningCursor3 source code" href="/blog/Samples/Silverlight/SpinningCursor4.zip"&gt;SpinningCursor4.zip&lt;/a&gt; (57 KB): Source (VS2008/Silverlight 2.0)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Series History&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Part 4: Adding an animation (static XAML) to the slices (in Silverlight/C#)  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.nimblecoder.com/blog/archive/2008/10/29/spinning-wait-symbol-in-silverlight-part3.aspx"&gt;Part 3: Adding curvature to the slices (in Silverlight/C#)&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.nimblecoder.com/blog/archive/2008/10/20/spinning-wait-symbol-in-silverlight-part-2.aspx"&gt;Part 2: Dynamically building slices (in Silverlight/C#)&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.nimblecoder.com/blog/archive/2008/10/08/spinning-wait-symbol-in-silverlight.aspx"&gt;Part 1: Treo-like wait symbol in static XAML&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;a href="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/SpinningWaitSymbolinSilverlightPart4_9F71/SpinningCursor4TestPage.png"&gt;&lt;/a&gt; &lt;/p&gt; &lt;h4&gt;Introduction&lt;/h4&gt; &lt;p&gt;The goal of these posts is to build a spinning cursor similar to the &lt;a href="http://en.wikipedia.org/wiki/Spinning_wait_cursor_(Mac_OS_X)"&gt;Mac OS X wait cursor&lt;/a&gt; through programmatic means in &lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt;. The cursor is still very rough and will undergo improvements progrressively. One of the reasons to build the cursor programmatically is to have more control over the output such as changing the number of slices or rotation or other parameters.&lt;/p&gt; &lt;p&gt;For this post, I added an animation to the rotation angle of the canvas which causes the slices to spin. I also added a simple navigation to the previous examples.&lt;/p&gt; &lt;div&gt; &lt;iframe src="/samples/Silverlight/SpinningCursor4.Web/SpinningCursorTestPage.html" width="500" height="280"&gt; &lt;p&gt;Download Silverlight&lt;/p&gt; &lt;/iframe&gt; &lt;/div&gt; &lt;h4&gt;Step 1: Adding the Animation&lt;/h4&gt; &lt;p&gt;In the previous post, I had one canvas for the background image as well as the slices. This time I realized I needed two canvases: one for the background and one for the slices. I needed separate canvases so that I could apply a rotation transform animation to the slices without affecting the background image. I used Expression Blend 2.0 sp1 and selected the "SpinningCanvas" and added an Storyboard named "SpinStoryboard". I then changed the Angle of the RotateTransform from 0 - 360° for the time range 0.0 - 2.0 sec.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/SpinningWaitSymbolinSilverlightPart4_9F71/SpinningCursor4BlendAnimation.png"&gt;&lt;img height="369" alt="SpinningCursor4-BlendAnimation" src="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/SpinningWaitSymbolinSilverlightPart4_9F71/SpinningCursor4BlendAnimation_thumb.png" width="640" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;This resulted in the following XAML:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl.Resources&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Storyboard &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;="SpinStoryboard" &lt;/span&gt;&lt;span style="color: red"&gt;RepeatBehavior&lt;/span&gt;&lt;span style="color: blue"&gt;="Forever"&amp;gt;
&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;DoubleAnimationUsingKeyFrames
            &lt;/span&gt;&lt;span style="color: red"&gt;BeginTime&lt;/span&gt;&lt;span style="color: blue"&gt;="00:00:00"
            &lt;/span&gt;&lt;span style="color: red"&gt;Storyboard.TargetName&lt;/span&gt;&lt;span style="color: blue"&gt;="SpinningCanvas"
            &lt;/span&gt;&lt;span style="color: red"&gt;Storyboard.TargetProperty&lt;/span&gt;&lt;span style="color: blue"&gt;="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"&amp;gt;
&lt;/span&gt;&lt;span&gt;            &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;SplineDoubleKeyFrame &lt;/span&gt;&lt;span style="color: red"&gt;KeyTime&lt;/span&gt;&lt;span style="color: blue"&gt;="00:00:02" &lt;/span&gt;&lt;span style="color: red"&gt;Value&lt;/span&gt;&lt;span style="color: blue"&gt;="360"/&amp;gt;
&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Storyboard&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl.Resources&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;h4&gt;Step 2: Starting the Animation&lt;/h4&gt;
&lt;p&gt;When the control is created or updated, the Update() method is called. I modified the method as follows:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: navy"&gt;void &lt;/span&gt;&lt;span style="color: maroon"&gt;Update&lt;/span&gt;()
{
    &lt;span style="color: maroon"&gt;SpinStoryboard&lt;/span&gt;.&lt;span style="color: maroon"&gt;Stop&lt;/span&gt;();
    &lt;span style="color: maroon"&gt;CursorCanvas&lt;/span&gt;.&lt;span style="color: maroon"&gt;Children&lt;/span&gt;.&lt;span style="color: maroon"&gt;Clear&lt;/span&gt;();
    &lt;span style="color: maroon"&gt;SpinningCanvas&lt;/span&gt;.&lt;span style="color: maroon"&gt;Children&lt;/span&gt;.&lt;span style="color: maroon"&gt;Clear&lt;/span&gt;();
    &lt;span style="color: maroon"&gt;CreateOutlineGuides&lt;/span&gt;(&lt;span style="color: maroon"&gt;CursorCanvas&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;CreateBackground&lt;/span&gt;(&lt;span style="color: maroon"&gt;CursorCanvas&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;CreateSlicePaths&lt;/span&gt;(&lt;span style="color: maroon"&gt;SpinningCanvas&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;SpinStoryboard&lt;/span&gt;.&lt;span style="color: maroon"&gt;Begin&lt;/span&gt;();
}
&lt;/pre&gt;
&lt;h4&gt;Step 3: Adding the Sample Navigation&lt;/h4&gt;
&lt;p&gt;I wanted to support future samples, so I used reflection to find all of the UserControls not including App or Page. I used a Dictionary&amp;lt;string, Type&amp;gt; to map the Type.Name with the Type in case I need it for future samples. I then dynamically created a button for each sample.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: navy"&gt;void &lt;/span&gt;&lt;span style="color: maroon"&gt;Page_Loaded&lt;/span&gt;(&lt;span style="color: navy"&gt;object &lt;/span&gt;&lt;span style="color: maroon"&gt;sender&lt;/span&gt;, &lt;span style="color: #a65300"&gt;RoutedEventArgs &lt;/span&gt;&lt;span style="color: maroon"&gt;e&lt;/span&gt;)
{
    &lt;span style="color: #a65300"&gt;Assembly &lt;/span&gt;&lt;span style="color: maroon"&gt;assembly &lt;/span&gt;= &lt;span style="color: #a65300"&gt;Assembly&lt;/span&gt;.&lt;span style="color: maroon"&gt;GetExecutingAssembly&lt;/span&gt;();
    &lt;span style="color: #a65300"&gt;Type&lt;/span&gt;[] &lt;span style="color: maroon"&gt;exportedTypes &lt;/span&gt;= &lt;span style="color: maroon"&gt;assembly&lt;/span&gt;.&lt;span style="color: maroon"&gt;GetExportedTypes&lt;/span&gt;();
    &lt;span style="color: navy"&gt;foreach &lt;/span&gt;(&lt;span style="color: #a65300"&gt;Type &lt;/span&gt;&lt;span style="color: maroon"&gt;t &lt;/span&gt;&lt;span style="color: navy"&gt;in &lt;/span&gt;&lt;span style="color: maroon"&gt;exportedTypes&lt;/span&gt;)
    {
        &lt;span style="color: green"&gt;// Testing various inheritance detection methods
        &lt;/span&gt;&lt;span style="color: navy"&gt;bool &lt;/span&gt;&lt;span style="color: maroon"&gt;isNotApp &lt;/span&gt;= (&lt;span style="color: maroon"&gt;t &lt;/span&gt;!= &lt;span style="color: navy"&gt;typeof&lt;/span&gt;(&lt;span style="color: #a65300"&gt;App&lt;/span&gt;));
        &lt;span style="color: navy"&gt;bool &lt;/span&gt;&lt;span style="color: maroon"&gt;isNotSelf &lt;/span&gt;= (&lt;span style="color: maroon"&gt;t &lt;/span&gt;!= &lt;span style="color: navy"&gt;this&lt;/span&gt;.&lt;span style="color: maroon"&gt;GetType&lt;/span&gt;());
        &lt;span style="color: navy"&gt;bool &lt;/span&gt;&lt;span style="color: maroon"&gt;isUserControl &lt;/span&gt;= &lt;span style="color: maroon"&gt;t&lt;/span&gt;.&lt;span style="color: maroon"&gt;IsSubclassOf&lt;/span&gt;(&lt;span style="color: navy"&gt;typeof&lt;/span&gt;(&lt;span style="color: #a65300"&gt;UserControl&lt;/span&gt;));

        &lt;span style="color: navy"&gt;if &lt;/span&gt;(&lt;span style="color: maroon"&gt;isNotApp &lt;/span&gt;&amp;amp;&amp;amp; &lt;span style="color: maroon"&gt;isNotSelf &lt;/span&gt;&amp;amp;&amp;amp; &lt;span style="color: maroon"&gt;isUserControl&lt;/span&gt;)
        {
            &lt;span style="color: maroon"&gt;_implementedTypes&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;t&lt;/span&gt;.&lt;span style="color: maroon"&gt;Name&lt;/span&gt;, &lt;span style="color: maroon"&gt;t&lt;/span&gt;);
        }
    }

    &lt;span style="color: #a65300"&gt;Button &lt;/span&gt;&lt;span style="color: maroon"&gt;lastButton &lt;/span&gt;= &lt;span style="color: navy"&gt;null&lt;/span&gt;;

    &lt;span style="color: green"&gt;// Sort the names of the UserControls to make more sense
    &lt;/span&gt;&lt;span style="color: #a65300"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: navy"&gt;string&lt;/span&gt;&amp;gt; &lt;span style="color: maroon"&gt;sortedKeys &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: navy"&gt;string&lt;/span&gt;&amp;gt;(&lt;span style="color: maroon"&gt;_implementedTypes&lt;/span&gt;.&lt;span style="color: maroon"&gt;Keys&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;sortedKeys&lt;/span&gt;.&lt;span style="color: maroon"&gt;Sort&lt;/span&gt;();

    &lt;span style="color: navy"&gt;for &lt;/span&gt;(&lt;span style="color: navy"&gt;int &lt;/span&gt;&lt;span style="color: maroon"&gt;index &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;; &lt;span style="color: maroon"&gt;index &lt;/span&gt;&amp;lt; &lt;span style="color: maroon"&gt;_implementedTypes&lt;/span&gt;.&lt;span style="color: maroon"&gt;Count&lt;/span&gt;; ++&lt;span style="color: maroon"&gt;index&lt;/span&gt;)
    {
        &lt;span style="color: navy"&gt;string &lt;/span&gt;&lt;span style="color: maroon"&gt;key &lt;/span&gt;= &lt;span style="color: maroon"&gt;sortedKeys&lt;/span&gt;[&lt;span style="color: maroon"&gt;index&lt;/span&gt;];
        &lt;span style="color: #a65300"&gt;Type &lt;/span&gt;&lt;span style="color: maroon"&gt;t &lt;/span&gt;= &lt;span style="color: maroon"&gt;_implementedTypes&lt;/span&gt;[&lt;span style="color: maroon"&gt;key&lt;/span&gt;];
        &lt;span style="color: maroon"&gt;lastButton &lt;/span&gt;= &lt;span style="color: maroon"&gt;AddButton&lt;/span&gt;(&lt;span style="color: maroon"&gt;t&lt;/span&gt;, &lt;span style="color: maroon"&gt;index&lt;/span&gt;);
    }

    &lt;span style="color: green"&gt;// Use the last UserControl for the initial display
    &lt;/span&gt;&lt;span style="color: navy"&gt;if &lt;/span&gt;(&lt;span style="color: maroon"&gt;lastButton &lt;/span&gt;!= &lt;span style="color: navy"&gt;null&lt;/span&gt;)
    {
        &lt;span style="color: maroon"&gt;Button_Click&lt;/span&gt;(&lt;span style="color: maroon"&gt;lastButton&lt;/span&gt;, &lt;span style="color: navy"&gt;null&lt;/span&gt;);
    }
}
&lt;/pre&gt;
&lt;p&gt;To make it simple, I used name of the UserControl for the Button.Content and in the Button_Click event I used System.Activator to create an instance of the class.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: navy"&gt;private void &lt;/span&gt;&lt;span style="color: maroon"&gt;Button_Click&lt;/span&gt;(&lt;span style="color: navy"&gt;object &lt;/span&gt;&lt;span style="color: maroon"&gt;sender&lt;/span&gt;, &lt;span style="color: #a65300"&gt;RoutedEventArgs &lt;/span&gt;&lt;span style="color: maroon"&gt;e&lt;/span&gt;)
{
    &lt;span style="color: #a65300"&gt;UIElement &lt;/span&gt;&lt;span style="color: maroon"&gt;control &lt;/span&gt;= &lt;span style="color: navy"&gt;null&lt;/span&gt;;

    &lt;span style="color: navy"&gt;try
    &lt;/span&gt;{
        &lt;span style="color: #a65300"&gt;Button &lt;/span&gt;&lt;span style="color: maroon"&gt;button &lt;/span&gt;= &lt;span style="color: maroon"&gt;sender &lt;/span&gt;&lt;span style="color: navy"&gt;as &lt;/span&gt;&lt;span style="color: #a65300"&gt;Button&lt;/span&gt;;
        &lt;span style="color: navy"&gt;string &lt;/span&gt;&lt;span style="color: maroon"&gt;typeName &lt;/span&gt;= &lt;span style="color: maroon"&gt;button&lt;/span&gt;.&lt;span style="color: maroon"&gt;Content &lt;/span&gt;&lt;span style="color: navy"&gt;as string&lt;/span&gt;;
        &lt;span style="color: #a65300"&gt;Type &lt;/span&gt;&lt;span style="color: maroon"&gt;type &lt;/span&gt;= &lt;span style="color: maroon"&gt;_implementedTypes&lt;/span&gt;[&lt;span style="color: maroon"&gt;typeName&lt;/span&gt;];
        &lt;span style="color: navy"&gt;object &lt;/span&gt;&lt;span style="color: maroon"&gt;instance &lt;/span&gt;= &lt;span style="color: maroon"&gt;System&lt;/span&gt;.&lt;span style="color: #a65300"&gt;Activator&lt;/span&gt;.&lt;span style="color: maroon"&gt;CreateInstance&lt;/span&gt;(&lt;span style="color: maroon"&gt;type&lt;/span&gt;);
        &lt;span style="color: maroon"&gt;control &lt;/span&gt;= &lt;span style="color: maroon"&gt;instance &lt;/span&gt;&lt;span style="color: navy"&gt;as &lt;/span&gt;&lt;span style="color: #a65300"&gt;UIElement&lt;/span&gt;;
    }
    &lt;span style="color: navy"&gt;catch &lt;/span&gt;(&lt;span style="color: #a65300"&gt;Exception &lt;/span&gt;&lt;span style="color: maroon"&gt;ex&lt;/span&gt;)
    {
        &lt;span style="color: maroon"&gt;System&lt;/span&gt;.&lt;span style="color: maroon"&gt;Diagnostics&lt;/span&gt;.&lt;span style="color: #a65300"&gt;Debug&lt;/span&gt;.&lt;span style="color: maroon"&gt;WriteLine&lt;/span&gt;(&lt;span style="color: maroon"&gt;ex&lt;/span&gt;.&lt;span style="color: maroon"&gt;ToString&lt;/span&gt;());
    }

    &lt;span style="color: maroon"&gt;WorkArea&lt;/span&gt;.&lt;span style="color: maroon"&gt;Children&lt;/span&gt;.&lt;span style="color: maroon"&gt;Clear&lt;/span&gt;();
    &lt;span style="color: navy"&gt;if &lt;/span&gt;(&lt;span style="color: maroon"&gt;control &lt;/span&gt;!= &lt;span style="color: navy"&gt;null&lt;/span&gt;)
        &lt;span style="color: maroon"&gt;WorkArea&lt;/span&gt;.&lt;span style="color: maroon"&gt;Children&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;control&lt;/span&gt;);
}&lt;/pre&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;The animation looks nice and adds a lot to the overall effect. For the next part, I plan to dynamically create the animation instead of using Blend and perhaps improve the background shape to more closely resemble the Mac OS X spinning cursor.&lt;/p&gt;
&lt;div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.nimblecoder.com%2fblog%2farchive%2f2008%2f11%2f06%2fspinning-wait-symbol-in-silverlight-part4.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.nimblecoder.com%2fblog%2farchive%2f2008%2f11%2f06%2fspinning-wait-symbol-in-silverlight-part4.aspx&amp;amp;border=9CCFF&amp;amp;fgcolor=9CCFF&amp;amp;bgcolor=9CCFF&amp;amp;cfgcolor=9CCFF&amp;amp;cbgcolor=9CCFF" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a18b93fb-92fa-4217-9e65-8066a74a613a" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/C%23" rel="tag"&gt;C#&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;&lt;/div&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/75.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=CycLGMvdFJ8:EXT9idGn_N8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=CycLGMvdFJ8:EXT9idGn_N8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=CycLGMvdFJ8:EXT9idGn_N8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=CycLGMvdFJ8:EXT9idGn_N8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=CycLGMvdFJ8:EXT9idGn_N8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/11/06/spinning-wait-symbol-in-silverlight-part4.aspx</guid>
            <pubDate>Thu, 06 Nov 2008 08:03:05 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/75.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/11/06/spinning-wait-symbol-in-silverlight-part4.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/75.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/75.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/11/06/spinning-wait-symbol-in-silverlight-part4.aspx</feedburner:origLink></item>
        <item>
            <title>Spinning Wait Symbol in Silverlight, Part3</title>
            <category>C#</category>
            <category>SilverLight</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/sOoW04q_ZRc/spinning-wait-symbol-in-silverlight-part3.aspx</link>
            <description>&lt;div&gt;&lt;a href="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/SpinningWaitSymbolinSilverlightPart3_94A2/SpinningCursor3TestPage.png"&gt;&lt;img height="249" alt="SpinningCursor3-TestPage" src="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/SpinningWaitSymbolinSilverlightPart3_94A2/SpinningCursor3TestPage_thumb.png" width="231" align="right" /&gt;&lt;/a&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;a title="SpinningCursor3 source code" href="/blog/Samples/Silverlight/SpinningCursor3.zip"&gt;SpinningCursor3.zip&lt;/a&gt; (34 KB): Source (VS2008/Silverlight 2.0)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Series History&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Part 3: Adding curvature to the slices (in Silverlight/C#)  &lt;/li&gt;&lt;li&gt;&lt;a href="/blog/archive/2008/10/20/spinning-wait-symbol-in-silverlight-part-2.aspx"&gt;Part 2: Dynamically building slices (in Silverlight/C#)&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="/blog/archive/2008/10/08/spinning-wait-symbol-in-silverlight.aspx"&gt;Part 1: Treo-like wait symbol in static XAML&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;In this post, I add curvature to the slices and refactor the code to support upcoming features. The goal of these posts is to build a spinning cursor similar to the &lt;a href="http://en.wikipedia.org/wiki/Spinning_wait_cursor_(Mac_OS_X)"&gt;Mac OS X wait cursor&lt;/a&gt; through programmatic means in &lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt;. One of the reasons to build the cursor programmatically is to create it will different number of slices or rotation or other parameters. At this point, the cursor is still very rough and just beginning to resemble the final result. In upcoming posts, I will animate the cursor and adjust the appearance to more closely resemble the desired cursor.&lt;/p&gt; &lt;h4&gt;Step 1: Adjust the cursor properties&lt;/h4&gt; &lt;p&gt;I added AlternateSlices and Origin properties, and also DefaultSliceCount and DefaultRotationAngle to the class.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: navy"&gt;public static readonly int &lt;/span&gt;&lt;span style="color: maroon"&gt;DefaultSliceCount &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;10&lt;/span&gt;;
&lt;span style="color: navy"&gt;public static readonly double &lt;/span&gt;&lt;span style="color: maroon"&gt;DefaultSliceRotationAngle &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;360.0&lt;/span&gt; / &lt;span style="color: maroon"&gt;DefaultSliceCount&lt;/span&gt;;

&lt;span style="background: #e0e0ff; color: gray"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="background: #e0e0ff; color: gray"&gt;/// &lt;/span&gt;&lt;span style="background: #e0e0ff; color: green"&gt;Show alternating slices (true) or all slices (false) &lt;/span&gt;       
&lt;span style="background: #e0e0ff; color: gray"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
&lt;span style="color: navy"&gt;public bool &lt;/span&gt;&lt;span style="color: maroon"&gt;AlternateSlices &lt;/span&gt;{ &lt;span style="color: navy"&gt;get&lt;/span&gt;; &lt;span style="color: navy"&gt;set&lt;/span&gt;; }

&lt;span style="background: #e0e0ff; color: gray"&gt;/// &amp;lt;summary&amp;gt; &lt;/span&gt;       
&lt;span style="background: #e0e0ff; color: gray"&gt;/// &lt;/span&gt;&lt;span style="background: #e0e0ff; color: green"&gt;The origin of the ellipse for the spinning cursor &lt;/span&gt;
&lt;span style="background: #e0e0ff; color: gray"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt;
&lt;span style="color: navy"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Point &lt;/span&gt;&lt;span style="color: maroon"&gt;Origin &lt;/span&gt;{ &lt;span style="color: navy"&gt;get&lt;/span&gt;; &lt;span style="color: navy"&gt;private set&lt;/span&gt;; }
&lt;/pre&gt;
&lt;h4&gt;Step 2: Set the default parameter values&lt;/h4&gt;
&lt;p&gt;I specified the default slice count and the radius and origin of the cursor.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: navy"&gt;void &lt;/span&gt;&lt;span style="color: maroon"&gt;Page_Loaded&lt;/span&gt;(&lt;span style="color: navy"&gt;object &lt;/span&gt;&lt;span style="color: maroon"&gt;sender&lt;/span&gt;, &lt;span style="color: #a65300"&gt;RoutedEventArgs &lt;/span&gt;&lt;span style="color: maroon"&gt;e&lt;/span&gt;)
{
    &lt;span style="color: maroon"&gt;txtVersion&lt;/span&gt;.&lt;span style="color: maroon"&gt;Text &lt;/span&gt;= &lt;span style="color: navy"&gt;this&lt;/span&gt;.&lt;span style="color: maroon"&gt;GetType&lt;/span&gt;().&lt;span style="color: maroon"&gt;Name&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;AlternateSlices &lt;/span&gt;= &lt;span style="color: navy"&gt;true&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;SliceCount &lt;/span&gt;= &lt;span style="color: maroon"&gt;DefaultSliceCount&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;txtSliceCount&lt;/span&gt;.&lt;span style="color: maroon"&gt;Text &lt;/span&gt;= &lt;span style="color: #a65300"&gt;Convert&lt;/span&gt;.&lt;span style="color: maroon"&gt;ToString&lt;/span&gt;(&lt;span style="color: maroon"&gt;SliceCount&lt;/span&gt;);

    &lt;span style="color: maroon"&gt;SliceRotationAngle &lt;/span&gt;= &lt;span style="color: maroon"&gt;DefaultSliceRotationAngle&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;txtRotation&lt;/span&gt;.&lt;span style="color: maroon"&gt;Text &lt;/span&gt;= &lt;span style="color: #a65300"&gt;Convert&lt;/span&gt;.&lt;span style="color: maroon"&gt;ToString&lt;/span&gt;(&lt;span style="color: maroon"&gt;SliceRotationAngle&lt;/span&gt;);

    &lt;span style="color: maroon"&gt;RadiusX &lt;/span&gt;= &lt;span style="color: maroon"&gt;SpinningCanvas&lt;/span&gt;.&lt;span style="color: maroon"&gt;Width &lt;/span&gt;/ &lt;span style="background: #e6ffff"&gt;2.0&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;RadiusY &lt;/span&gt;= &lt;span style="color: maroon"&gt;SpinningCanvas&lt;/span&gt;.&lt;span style="color: maroon"&gt;Height &lt;/span&gt;/ &lt;span style="background: #e6ffff"&gt;2.0&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;Origin &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Point&lt;/span&gt;(&lt;span style="color: maroon"&gt;RadiusX&lt;/span&gt;, &lt;span style="color: maroon"&gt;RadiusY&lt;/span&gt;);

    &lt;span style="color: maroon"&gt;Update&lt;/span&gt;();
}
&lt;/pre&gt;
&lt;h4&gt;Step 3: Create a background circle (ellipse)&lt;/h4&gt;
&lt;p&gt;I used a simple linear gradient for now because the final gradient looks much more complicated and will take more time.&lt;/p&gt;
&lt;p /&gt;&lt;pre class="code"&gt;&lt;span style="color: navy"&gt;void &lt;/span&gt;&lt;span style="color: maroon"&gt;CreateBackground&lt;/span&gt;(&lt;span style="color: #a65300"&gt;Canvas &lt;/span&gt;&lt;span style="color: maroon"&gt;cursorCanvas&lt;/span&gt;)
{
    &lt;span style="color: #a65300"&gt;GradientBrush &lt;/span&gt;&lt;span style="color: maroon"&gt;brush &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;LinearGradientBrush&lt;/span&gt;();
    &lt;span style="color: #a65300"&gt;GradientStop &lt;/span&gt;&lt;span style="color: maroon"&gt;stop1 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;GradientStop&lt;/span&gt;();
    &lt;span style="color: maroon"&gt;stop1&lt;/span&gt;.&lt;span style="color: maroon"&gt;Color &lt;/span&gt;= &lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.&lt;span style="color: maroon"&gt;FromArgb&lt;/span&gt;(&lt;span style="background: #e6ffff"&gt;255&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;255&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;stop1&lt;/span&gt;.&lt;span style="color: maroon"&gt;Offset &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;0.25&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;brush&lt;/span&gt;.&lt;span style="color: maroon"&gt;GradientStops&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;stop1&lt;/span&gt;);

    &lt;span style="color: #a65300"&gt;GradientStop &lt;/span&gt;&lt;span style="color: maroon"&gt;stop2 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;GradientStop&lt;/span&gt;();
    &lt;span style="color: maroon"&gt;stop2&lt;/span&gt;.&lt;span style="color: maroon"&gt;Color &lt;/span&gt;= &lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.&lt;span style="color: maroon"&gt;FromArgb&lt;/span&gt;(&lt;span style="background: #e6ffff"&gt;255&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;255&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;stop2&lt;/span&gt;.&lt;span style="color: maroon"&gt;Offset &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;0.5&lt;/span&gt;; &lt;span style="color: green"&gt;// cursorCanvas.Width / 2.0;
    &lt;/span&gt;&lt;span style="color: maroon"&gt;brush&lt;/span&gt;.&lt;span style="color: maroon"&gt;GradientStops&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;stop2&lt;/span&gt;);

    &lt;span style="color: #a65300"&gt;GradientStop &lt;/span&gt;&lt;span style="color: maroon"&gt;stop3 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;GradientStop&lt;/span&gt;();
    &lt;span style="color: maroon"&gt;stop3&lt;/span&gt;.&lt;span style="color: maroon"&gt;Color &lt;/span&gt;= &lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.&lt;span style="color: maroon"&gt;FromArgb&lt;/span&gt;(&lt;span style="background: #e6ffff"&gt;255&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;255&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;stop3&lt;/span&gt;.&lt;span style="color: maroon"&gt;Offset &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;0.75&lt;/span&gt;; &lt;span style="color: green"&gt;// cursorCanvas.Width;
    &lt;/span&gt;&lt;span style="color: maroon"&gt;brush&lt;/span&gt;.&lt;span style="color: maroon"&gt;GradientStops&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;stop3&lt;/span&gt;);

    &lt;span style="color: #a65300"&gt;Ellipse &lt;/span&gt;&lt;span style="color: maroon"&gt;ellipse &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;Ellipse&lt;/span&gt;();
    &lt;span style="color: maroon"&gt;ellipse&lt;/span&gt;.&lt;span style="color: maroon"&gt;Height &lt;/span&gt;= &lt;span style="color: maroon"&gt;cursorCanvas&lt;/span&gt;.&lt;span style="color: maroon"&gt;Height&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;ellipse&lt;/span&gt;.&lt;span style="color: maroon"&gt;Width &lt;/span&gt;= &lt;span style="color: maroon"&gt;cursorCanvas&lt;/span&gt;.&lt;span style="color: maroon"&gt;Width&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;ellipse&lt;/span&gt;.&lt;span style="color: maroon"&gt;Fill &lt;/span&gt;= &lt;span style="color: maroon"&gt;brush&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;cursorCanvas&lt;/span&gt;.&lt;span style="color: maroon"&gt;Children&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;ellipse&lt;/span&gt;);
}
&lt;/pre&gt;
&lt;h4&gt;Step 4: Implement the alternating slices&lt;/h4&gt;
&lt;p /&gt;
&lt;p&gt;Implementing the alternating slices was simple:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: #e0e0ff; color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="background: #e0e0ff; color: green"&gt;Create an ellipse using rotated slices to build the ellipse
&lt;/span&gt;&lt;span style="background: #e0e0ff; color: gray"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color: navy"&gt;void &lt;/span&gt;&lt;span style="color: maroon"&gt;CreateSlicePaths&lt;/span&gt;(&lt;span style="color: #a65300"&gt;Canvas &lt;/span&gt;&lt;span style="color: maroon"&gt;cursorCanvas&lt;/span&gt;)
{
    &lt;span style="color: green"&gt;// Create Slices
    &lt;/span&gt;&lt;span style="color: navy"&gt;for &lt;/span&gt;(&lt;span style="color: navy"&gt;int &lt;/span&gt;&lt;span style="color: maroon"&gt;index &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;; &lt;span style="color: maroon"&gt;index &lt;/span&gt;&amp;lt; &lt;span style="color: maroon"&gt;SliceCount&lt;/span&gt;; ++&lt;span style="color: maroon"&gt;index&lt;/span&gt;)
    {
        &lt;span style="color: #a65300"&gt;PathFigure &lt;/span&gt;&lt;span style="color: maroon"&gt;pathFigure &lt;/span&gt;= &lt;span style="color: maroon"&gt;CreateSliceFigure&lt;/span&gt;();

        &lt;span style="color: #a65300"&gt;PathGeometry &lt;/span&gt;&lt;span style="color: maroon"&gt;pathGeometry &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;PathGeometry&lt;/span&gt;();
        &lt;span style="color: maroon"&gt;pathGeometry&lt;/span&gt;.&lt;span style="color: maroon"&gt;Figures&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;);

        &lt;span style="color: #a65300"&gt;Path &lt;/span&gt;&lt;span style="color: maroon"&gt;path &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;Path&lt;/span&gt;();
        &lt;span style="color: maroon"&gt;path&lt;/span&gt;.&lt;span style="color: maroon"&gt;Stroke &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;SolidColorBrush&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.&lt;span style="color: maroon"&gt;FromArgb&lt;/span&gt;(&lt;span style="background: #e6ffff"&gt;128&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;));
        &lt;span style="color: maroon"&gt;path&lt;/span&gt;.&lt;span style="color: maroon"&gt;StrokeThickness &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;1.0&lt;/span&gt;;
        &lt;span style="color: maroon"&gt;path&lt;/span&gt;.&lt;span style="color: maroon"&gt;Fill &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;SolidColorBrush&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.&lt;span style="color: maroon"&gt;FromArgb&lt;/span&gt;(&lt;span style="background: #e6ffff"&gt;192&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;128&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;128&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;128&lt;/span&gt;));
        &lt;span style="color: maroon"&gt;path&lt;/span&gt;.&lt;span style="color: maroon"&gt;Data &lt;/span&gt;= &lt;span style="color: maroon"&gt;pathGeometry&lt;/span&gt;;

        &lt;span style="color: green"&gt;// Rotate the slice for all slices after the first slice
        &lt;/span&gt;&lt;span style="color: navy"&gt;if &lt;/span&gt;(&lt;span style="color: maroon"&gt;index &lt;/span&gt;&amp;gt; &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;)
        {
            &lt;span style="color: #a65300"&gt;RotateTransform &lt;/span&gt;&lt;span style="color: maroon"&gt;t1 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;RotateTransform&lt;/span&gt;();
            &lt;span style="color: maroon"&gt;t1&lt;/span&gt;.&lt;span style="color: maroon"&gt;CenterX &lt;/span&gt;= &lt;span style="color: maroon"&gt;RadiusX&lt;/span&gt;;
            &lt;span style="color: maroon"&gt;t1&lt;/span&gt;.&lt;span style="color: maroon"&gt;CenterY &lt;/span&gt;= &lt;span style="color: maroon"&gt;RadiusY&lt;/span&gt;;
            &lt;span style="color: maroon"&gt;t1&lt;/span&gt;.&lt;span style="color: maroon"&gt;Angle &lt;/span&gt;= &lt;span style="color: maroon"&gt;SliceCenterAngle &lt;/span&gt;* &lt;span style="color: maroon"&gt;index&lt;/span&gt;;

            &lt;span style="color: #a65300"&gt;TransformGroup &lt;/span&gt;&lt;span style="color: maroon"&gt;transformGroup &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;TransformGroup&lt;/span&gt;();
            &lt;span style="color: maroon"&gt;transformGroup&lt;/span&gt;.&lt;span style="color: maroon"&gt;Children&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;t1&lt;/span&gt;);
            &lt;span style="color: maroon"&gt;path&lt;/span&gt;.&lt;span style="color: maroon"&gt;RenderTransform &lt;/span&gt;= &lt;span style="color: maroon"&gt;transformGroup&lt;/span&gt;;
        }

        &lt;span style="color: maroon"&gt;cursorCanvas&lt;/span&gt;.&lt;span style="color: maroon"&gt;Children&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;path&lt;/span&gt;);

        &lt;span style="color: navy"&gt;if &lt;/span&gt;(&lt;span style="color: maroon"&gt;AlternateSlices&lt;/span&gt;)
            ++&lt;span style="color: maroon"&gt;index&lt;/span&gt;;
    }
}
&lt;/pre&gt;
&lt;h4&gt;Step 5: Add the curvature to the slices&lt;/h4&gt;
&lt;p&gt;The curvature isn't perfect, but it looks fine with the default settings (10 slices and 36° rotation). I used a Bezier curve, but perhaps the standard arc would work better in the future.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Curve control weighting
&lt;/span&gt;&lt;span style="color: navy"&gt;double &lt;/span&gt;&lt;span style="color: maroon"&gt;curveWeight &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;0.75&lt;/span&gt;;

&lt;span style="color: green"&gt;// Create the first line
&lt;/span&gt;&lt;span style="color: #a65300"&gt;BezierSegment &lt;/span&gt;&lt;span style="color: maroon"&gt;seg1 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;BezierSegment&lt;/span&gt;();
&lt;span style="color: maroon"&gt;seg1&lt;/span&gt;.&lt;span style="color: maroon"&gt;Point1 &lt;/span&gt;= &lt;span style="color: maroon"&gt;point0&lt;/span&gt;;
&lt;span style="color: maroon"&gt;seg1&lt;/span&gt;.&lt;span style="color: maroon"&gt;Point2 &lt;/span&gt;= &lt;span style="color: maroon"&gt;CalculatePointOnEllipse&lt;/span&gt;(&lt;span style="background: #e6ffff"&gt;0.0&lt;/span&gt;, &lt;span style="color: maroon"&gt;RadiusX &lt;/span&gt;* &lt;span style="color: maroon"&gt;curveWeight&lt;/span&gt;, &lt;span style="color: maroon"&gt;RadiusY &lt;/span&gt;* &lt;span style="color: maroon"&gt;curveWeight&lt;/span&gt;, &lt;span style="color: maroon"&gt;Origin&lt;/span&gt;);
&lt;span style="color: maroon"&gt;seg1&lt;/span&gt;.&lt;span style="color: maroon"&gt;Point3 &lt;/span&gt;= &lt;span style="color: maroon"&gt;point1&lt;/span&gt;;
&lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;.&lt;span style="color: maroon"&gt;Segments&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;seg1&lt;/span&gt;);

&lt;span style="color: green"&gt;// Use an arc for the circular side
&lt;/span&gt;&lt;span style="color: #a65300"&gt;ArcSegment &lt;/span&gt;&lt;span style="color: maroon"&gt;seg2 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;ArcSegment&lt;/span&gt;();
&lt;span style="color: maroon"&gt;seg2&lt;/span&gt;.&lt;span style="color: maroon"&gt;Point &lt;/span&gt;= &lt;span style="color: maroon"&gt;point2&lt;/span&gt;;
&lt;span style="color: maroon"&gt;seg2&lt;/span&gt;.&lt;span style="color: maroon"&gt;Size &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Size&lt;/span&gt;(&lt;span style="color: maroon"&gt;RadiusX&lt;/span&gt;, &lt;span style="color: maroon"&gt;RadiusY&lt;/span&gt;);
&lt;span style="color: maroon"&gt;seg2&lt;/span&gt;.&lt;span style="color: maroon"&gt;RotationAngle &lt;/span&gt;= &lt;span style="color: maroon"&gt;SliceCenterAngle&lt;/span&gt;;
&lt;span style="color: maroon"&gt;seg2&lt;/span&gt;.&lt;span style="color: maroon"&gt;IsLargeArc &lt;/span&gt;= (&lt;span style="color: maroon"&gt;SliceCenterAngle &lt;/span&gt;&amp;gt; &lt;span style="background: #e6ffff"&gt;180.0&lt;/span&gt;);
&lt;span style="color: maroon"&gt;seg2&lt;/span&gt;.&lt;span style="color: maroon"&gt;SweepDirection &lt;/span&gt;= &lt;span style="color: #2b91af"&gt;SweepDirection&lt;/span&gt;.&lt;span style="color: maroon"&gt;Counterclockwise&lt;/span&gt;;
&lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;.&lt;span style="color: maroon"&gt;Segments&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;seg2&lt;/span&gt;);

&lt;span style="color: green"&gt;// Close shape by going back to the starting point
&lt;/span&gt;&lt;span style="color: #a65300"&gt;BezierSegment &lt;/span&gt;&lt;span style="color: maroon"&gt;seg3 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;BezierSegment&lt;/span&gt;();
&lt;span style="color: maroon"&gt;seg3&lt;/span&gt;.&lt;span style="color: maroon"&gt;Point1 &lt;/span&gt;= &lt;span style="color: maroon"&gt;point2&lt;/span&gt;;
&lt;span style="color: maroon"&gt;seg3&lt;/span&gt;.&lt;span style="color: maroon"&gt;Point2 &lt;/span&gt;= &lt;span style="color: maroon"&gt;CalculatePointOnEllipse&lt;/span&gt;(&lt;span style="color: maroon"&gt;SliceCenterAngle&lt;/span&gt;, &lt;span style="color: maroon"&gt;RadiusX &lt;/span&gt;* &lt;span style="color: maroon"&gt;curveWeight&lt;/span&gt;, &lt;span style="color: maroon"&gt;RadiusY &lt;/span&gt;* &lt;span style="color: maroon"&gt;curveWeight&lt;/span&gt;, &lt;span style="color: maroon"&gt;Origin&lt;/span&gt;);
&lt;span style="color: maroon"&gt;seg3&lt;/span&gt;.&lt;span style="color: maroon"&gt;Point3 &lt;/span&gt;= &lt;span style="color: maroon"&gt;point0&lt;/span&gt;;
&lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;.&lt;span style="color: maroon"&gt;Segments&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;seg3&lt;/span&gt;);
&lt;/pre&gt;
&lt;p /&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;The spinning cursor now has a dynamic number of slices and rotation angle, and it is starting to look more like the desired result. In the next post, I will animate the cursor to give it the spinning effect.&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:88d816bf-b129-4f1d-8932-0f80148948d6" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/C%23" rel="tag"&gt;C#&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.nimblecoder.com%2fblog%2farchive%2f2008%2f10%2f29%2fspinning-wait-symbol-in-silverlight-part3.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.nimblecoder.com%2fblog%2farchive%2f2008%2f10%2f29%2fspinning-wait-symbol-in-silverlight-part3.aspx" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/74.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=sOoW04q_ZRc:rvjucDM3b8k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=sOoW04q_ZRc:rvjucDM3b8k:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=sOoW04q_ZRc:rvjucDM3b8k:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=sOoW04q_ZRc:rvjucDM3b8k:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=sOoW04q_ZRc:rvjucDM3b8k:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/10/29/spinning-wait-symbol-in-silverlight-part3.aspx</guid>
            <pubDate>Wed, 29 Oct 2008 16:16:42 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/74.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/10/29/spinning-wait-symbol-in-silverlight-part3.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/74.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/74.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/10/29/spinning-wait-symbol-in-silverlight-part3.aspx</feedburner:origLink></item>
        <item>
            <title>Spinning Wait Symbol in Silverlight, Part 2</title>
            <category>C#</category>
            <category>Programming</category>
            <category>SilverLight</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/POMBlMrRYq8/spinning-wait-symbol-in-silverlight-part-2.aspx</link>
            <description>&lt;p&gt;After my &lt;a href="http://www.nimblecoder.com/blog/archive/2008/10/08/spinning-wait-symbol-in-silverlight.aspx"&gt;previous spinning wait symbol&lt;/a&gt;, I decided to see how difficult it would be to create a &lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt; version of the &lt;a href="http://en.wikipedia.org/wiki/Spinning_wait_cursor_(Mac_OS_X)"&gt;Mac OSX wait cursor&lt;/a&gt; that I referenced in the &lt;a href="http://www.nimblecoder.com/blog/archive/2008/10/08/spinning-wait-symbol-in-silverlight.aspx"&gt;previous post&lt;/a&gt;. The Mac OSX cursor is commonly referred to as the "Spinning Pizza of Death" or the "Marble of Doom" and in fact there is a &lt;a href="http://marbleofdoom.com/"&gt;Marble of Doom&lt;/a&gt; web site dedicated to the amount of time spent waiting while watching the spinning cursor. The Marble of Doom web site has a very nice and large version of the cursor using Flash although it doesn't have any vector information but is using video frames (they probably just published the final product and did not include the vector/animation information). The purpose of this post is to programmatically build the cursor and then in later posts to animate it.&lt;/p&gt; &lt;h4&gt;Step 1: Decide on the initial interface properties&lt;/h4&gt; &lt;p&gt;I realized quickly that I would need a little geometry to programmatically build the cursor, but the first step was to build the interface requirements. The essential properties were:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: navy"&gt;public int &lt;/span&gt;&lt;span style="color: maroon"&gt;SliceCount &lt;/span&gt;{ &lt;span style="color: navy"&gt;get&lt;/span&gt;; &lt;span style="color: navy"&gt;set&lt;/span&gt;; }
&lt;span style="color: navy"&gt;public double &lt;/span&gt;&lt;span style="color: maroon"&gt;SliceCenterAngle &lt;/span&gt;{ &lt;span style="color: navy"&gt;get&lt;/span&gt;; &lt;span style="color: navy"&gt;private set&lt;/span&gt;; }
&lt;span style="color: navy"&gt;public double &lt;/span&gt;&lt;span style="color: maroon"&gt;SliceRotationAngle &lt;/span&gt;{ &lt;span style="color: navy"&gt;get&lt;/span&gt;; &lt;span style="color: navy"&gt;set&lt;/span&gt;; }
&lt;span style="color: navy"&gt;public double &lt;/span&gt;&lt;span style="color: maroon"&gt;RadiusX &lt;/span&gt;{ &lt;span style="color: navy"&gt;get&lt;/span&gt;; &lt;span style="color: navy"&gt;set&lt;/span&gt;; }
&lt;span style="color: navy"&gt;public double &lt;/span&gt;&lt;span style="color: maroon"&gt;RadiusY &lt;/span&gt;{ &lt;span style="color: navy"&gt;get&lt;/span&gt;; &lt;span style="color: navy"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;
&lt;p&gt;The &lt;span style="color: maroon"&gt;SliceCount&lt;/span&gt; determines how many slices or divisions to create, and the &lt;span style="color: maroon"&gt;SliceCenterAngle&lt;/span&gt; is simply 360° / &lt;span style="color: maroon"&gt;SliceCount&lt;/span&gt;. The &lt;span style="color: maroon"&gt;SliceRotationAngle&lt;/span&gt; is the angle to twist or bend the slice. I decided to have a &lt;span style="color: maroon"&gt;RadiusX&lt;/span&gt; and &lt;span style="color: maroon"&gt;RadiusY&lt;/span&gt; to support ellipses in the future as well.&lt;/p&gt;
&lt;h4&gt;Step 2: Manually create a slice&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/SpinningWaitSymbolinSilverlightPart2_96B0/SpinningCursor1-SliceInBlend.png"&gt;&lt;img height="147" alt="Manual slice in Blend" src="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/SpinningWaitSymbolinSilverlightPart2_96B0/SpinningCursor1-SliceInBlend_thumb.png" width="240" align="right" /&gt;&lt;/a&gt; Before I could programmatically create a slice, I needed to find out how to create a slice using XAML and Blend. The points on the slice would be in the center of the circle, and then two points on the circle determined by the &lt;span style="color: maroon"&gt;SliceCenterAngle&lt;/span&gt;. The biggest question was how to create the arc and maintain the circular appearance. Fortunately, the &lt;a href="http://msdn.microsoft.com/en-us/library/ms751808.aspx"&gt;Geometry Overview&lt;/a&gt; on MSDN was very helpful and got me started on the right track with the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.pathgeometry.aspx"&gt;PathGeometry&lt;/a&gt;. I was able to create the simplest scenario with a single slice from a circle with four slices:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Path &lt;/span&gt;&lt;span style="color: red"&gt;Stroke&lt;/span&gt;&lt;span style="color: blue"&gt;="Black" &lt;/span&gt;&lt;span style="color: red"&gt;StrokeThickness&lt;/span&gt;&lt;span style="color: blue"&gt;="1"&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Path.Data&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathGeometry&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;            &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathGeometry.Figures&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure &lt;/span&gt;&lt;span style="color: red"&gt;StartPoint&lt;/span&gt;&lt;span style="color: blue"&gt;="50,50"&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure.Segments&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LineSegment &lt;/span&gt;&lt;span style="color: red"&gt;Point&lt;/span&gt;&lt;span style="color: blue"&gt;="0,50" /&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ArcSegment &lt;/span&gt;&lt;span style="color: red"&gt;Size&lt;/span&gt;&lt;span style="color: blue"&gt;="50,50" &lt;/span&gt;&lt;span style="color: red"&gt;IsLargeArc&lt;/span&gt;&lt;span style="color: blue"&gt;="False"
                            &lt;/span&gt;&lt;span style="color: red"&gt;RotationAngle&lt;/span&gt;&lt;span style="color: blue"&gt;="90" &lt;/span&gt;&lt;span style="color: red"&gt;SweepDirection&lt;/span&gt;&lt;span style="color: blue"&gt;="CounterClockwise" &lt;/span&gt;&lt;span style="color: red"&gt;Point&lt;/span&gt;&lt;span style="color: blue"&gt;="50,100" /&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LineSegment &lt;/span&gt;&lt;span style="color: red"&gt;Point&lt;/span&gt;&lt;span style="color: blue"&gt;="50,50" /&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure.Segments&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;            &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathGeometry.Figures&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathGeometry&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Path.Data&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Path&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The next step was to create the same quarter-circle except with two slices:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Path &lt;/span&gt;&lt;span style="color: red"&gt;Stroke&lt;/span&gt;&lt;span style="color: blue"&gt;="Black" &lt;/span&gt;&lt;span style="color: red"&gt;StrokeThickness&lt;/span&gt;&lt;span style="color: blue"&gt;="1"&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Path.Data&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathGeometry&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;            &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathGeometry.Figures&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure &lt;/span&gt;&lt;span style="color: red"&gt;StartPoint&lt;/span&gt;&lt;span style="color: blue"&gt;="50,50"&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure.Segments&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LineSegment &lt;/span&gt;&lt;span style="color: red"&gt;Point&lt;/span&gt;&lt;span style="color: blue"&gt;="0,50" /&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ArcSegment
                            &lt;/span&gt;&lt;span style="color: red"&gt;Size&lt;/span&gt;&lt;span style="color: blue"&gt;="50,50"
                            &lt;/span&gt;&lt;span style="color: red"&gt;Point&lt;/span&gt;&lt;span style="color: blue"&gt;="14.645,85.355" 
                            &lt;/span&gt;&lt;span style="color: red"&gt;RotationAngle&lt;/span&gt;&lt;span style="color: blue"&gt;="45" 
                            &lt;/span&gt;&lt;span style="color: red"&gt;IsLargeArc&lt;/span&gt;&lt;span style="color: blue"&gt;="False"
                            &lt;/span&gt;&lt;span style="color: red"&gt;SweepDirection&lt;/span&gt;&lt;span style="color: blue"&gt;="CounterClockwise" 
                        /&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LineSegment &lt;/span&gt;&lt;span style="color: red"&gt;Point&lt;/span&gt;&lt;span style="color: blue"&gt;="50,50" /&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure.Segments&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                
                &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure &lt;/span&gt;&lt;span style="color: red"&gt;StartPoint&lt;/span&gt;&lt;span style="color: blue"&gt;="50,50"&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure.Segments&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LineSegment &lt;/span&gt;&lt;span style="color: red"&gt;Point&lt;/span&gt;&lt;span style="color: blue"&gt;="14.645,85.355" /&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ArcSegment
                            &lt;/span&gt;&lt;span style="color: red"&gt;Size&lt;/span&gt;&lt;span style="color: blue"&gt;="50,50"
                            &lt;/span&gt;&lt;span style="color: red"&gt;Point&lt;/span&gt;&lt;span style="color: blue"&gt;="50, 100" 
                            &lt;/span&gt;&lt;span style="color: red"&gt;RotationAngle&lt;/span&gt;&lt;span style="color: blue"&gt;="45" 
                            &lt;/span&gt;&lt;span style="color: red"&gt;IsLargeArc&lt;/span&gt;&lt;span style="color: blue"&gt;="False"
                            &lt;/span&gt;&lt;span style="color: red"&gt;SweepDirection&lt;/span&gt;&lt;span style="color: blue"&gt;="CounterClockwise" 
                        /&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LineSegment &lt;/span&gt;&lt;span style="color: red"&gt;Point&lt;/span&gt;&lt;span style="color: blue"&gt;="50,50" /&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure.Segments&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;                &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathFigure&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;            &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathGeometry.Figures&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;PathGeometry&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Path.Data&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Path&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;h4&gt;Step 3: Create a slice programmatically&lt;/h4&gt;
&lt;p&gt;The general idea is to create one slice and then rotate the slice around the circle to create the complete circle.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Create an ellipse using rotated slices to build the ellipse
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color: navy"&gt;void &lt;/span&gt;&lt;span style="color: maroon"&gt;CreateSlicePaths&lt;/span&gt;(&lt;span style="color: #a65300"&gt;Canvas &lt;/span&gt;&lt;span style="color: maroon"&gt;cursorCanvas&lt;/span&gt;)
{
    &lt;span style="color: maroon"&gt;SliceCenterAngle &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;360.0&lt;/span&gt; / &lt;span style="color: maroon"&gt;SliceCount&lt;/span&gt;;

    &lt;span style="color: green"&gt;// Create Slices
    &lt;/span&gt;&lt;span style="color: navy"&gt;for &lt;/span&gt;(&lt;span style="color: navy"&gt;int &lt;/span&gt;&lt;span style="color: maroon"&gt;index &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;; &lt;span style="color: maroon"&gt;index &lt;/span&gt;&amp;lt; &lt;span style="color: maroon"&gt;SliceCount&lt;/span&gt;; ++&lt;span style="color: maroon"&gt;index&lt;/span&gt;)
    {
        &lt;span style="color: #a65300"&gt;PathFigure &lt;/span&gt;&lt;span style="color: maroon"&gt;pathFigure &lt;/span&gt;= &lt;span style="color: maroon"&gt;CreateSliceFigure&lt;/span&gt;();

        &lt;span style="color: #a65300"&gt;PathGeometry &lt;/span&gt;&lt;span style="color: maroon"&gt;pathGeometry &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;PathGeometry&lt;/span&gt;();
        &lt;span style="color: maroon"&gt;pathGeometry&lt;/span&gt;.&lt;span style="color: maroon"&gt;Figures&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;);

        &lt;span style="color: #a65300"&gt;Path &lt;/span&gt;&lt;span style="color: maroon"&gt;path &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;Path&lt;/span&gt;();
        &lt;span style="color: maroon"&gt;path&lt;/span&gt;.&lt;span style="color: maroon"&gt;Stroke &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;SolidColorBrush&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Color&lt;/span&gt;.&lt;span style="color: maroon"&gt;FromArgb&lt;/span&gt;(&lt;span style="background: #e6ffff"&gt;255&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;));
        &lt;span style="color: maroon"&gt;path&lt;/span&gt;.&lt;span style="color: maroon"&gt;StrokeThickness &lt;/span&gt;= &lt;span style="background: #e6ffff"&gt;1.0&lt;/span&gt;;
        &lt;span style="color: maroon"&gt;path&lt;/span&gt;.&lt;span style="color: maroon"&gt;Data &lt;/span&gt;= &lt;span style="color: maroon"&gt;pathGeometry&lt;/span&gt;;

        &lt;span style="color: green"&gt;// Rotate the slice for all slices after the first slice
        &lt;/span&gt;&lt;span style="color: navy"&gt;if &lt;/span&gt;(&lt;span style="color: maroon"&gt;index &lt;/span&gt;&amp;gt; &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;)
        {
            &lt;span style="color: #a65300"&gt;RotateTransform &lt;/span&gt;&lt;span style="color: maroon"&gt;t1 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;RotateTransform&lt;/span&gt;();
            &lt;span style="color: maroon"&gt;t1&lt;/span&gt;.&lt;span style="color: maroon"&gt;CenterX &lt;/span&gt;= &lt;span style="color: maroon"&gt;RadiusX&lt;/span&gt;;
            &lt;span style="color: maroon"&gt;t1&lt;/span&gt;.&lt;span style="color: maroon"&gt;CenterY &lt;/span&gt;= &lt;span style="color: maroon"&gt;RadiusY&lt;/span&gt;;
            &lt;span style="color: maroon"&gt;t1&lt;/span&gt;.&lt;span style="color: maroon"&gt;Angle &lt;/span&gt;= &lt;span style="color: maroon"&gt;SliceCenterAngle &lt;/span&gt;* &lt;span style="color: maroon"&gt;index&lt;/span&gt;;

            &lt;span style="color: #a65300"&gt;TransformGroup &lt;/span&gt;&lt;span style="color: maroon"&gt;transformGroup &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;TransformGroup&lt;/span&gt;();
            &lt;span style="color: maroon"&gt;transformGroup&lt;/span&gt;.&lt;span style="color: maroon"&gt;Children&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;t1&lt;/span&gt;);
            &lt;span style="color: maroon"&gt;path&lt;/span&gt;.&lt;span style="color: maroon"&gt;RenderTransform &lt;/span&gt;= &lt;span style="color: maroon"&gt;transformGroup&lt;/span&gt;;
        }

        &lt;span style="color: maroon"&gt;cursorCanvas&lt;/span&gt;.&lt;span style="color: maroon"&gt;Children&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;path&lt;/span&gt;);
    }
}

&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Create the base shape for the slice
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color: navy"&gt;private &lt;/span&gt;&lt;span style="color: #a65300"&gt;PathFigure &lt;/span&gt;&lt;span style="color: maroon"&gt;CreateSliceFigure&lt;/span&gt;()
{
    &lt;span style="color: green"&gt;// Start at the center of the ellipse
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Point &lt;/span&gt;&lt;span style="color: maroon"&gt;point0 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Point&lt;/span&gt;(&lt;span style="color: maroon"&gt;RadiusX&lt;/span&gt;, &lt;span style="color: maroon"&gt;RadiusY&lt;/span&gt;);

    &lt;span style="color: green"&gt;// Next point is the left side of the ellipse
    //Point point1 = new Point(0.0, RadiusY); // if no rotation
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Point &lt;/span&gt;&lt;span style="color: maroon"&gt;point1 &lt;/span&gt;= &lt;span style="color: maroon"&gt;CalculatePointOnEllipse&lt;/span&gt;(&lt;span style="color: maroon"&gt;SliceRotationAngle&lt;/span&gt;);

    &lt;span style="color: green"&gt;// Calculate the bottom point on the ellipse
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Point &lt;/span&gt;&lt;span style="color: maroon"&gt;point2 &lt;/span&gt;= &lt;span style="color: maroon"&gt;CalculatePointOnEllipse&lt;/span&gt;(&lt;span style="color: maroon"&gt;SliceRotationAngle &lt;/span&gt;+ &lt;span style="color: maroon"&gt;SliceCenterAngle&lt;/span&gt;);

    &lt;span style="color: green"&gt;// Starting point
    &lt;/span&gt;&lt;span style="color: #a65300"&gt;PathFigure &lt;/span&gt;&lt;span style="color: maroon"&gt;pathFigure &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;PathFigure&lt;/span&gt;();
    &lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;.&lt;span style="color: maroon"&gt;StartPoint &lt;/span&gt;= &lt;span style="color: maroon"&gt;point0&lt;/span&gt;;

    &lt;span style="color: green"&gt;// Create the first line
    &lt;/span&gt;&lt;span style="color: #a65300"&gt;LineSegment &lt;/span&gt;&lt;span style="color: maroon"&gt;seg1 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;LineSegment&lt;/span&gt;();
    &lt;span style="color: maroon"&gt;seg1&lt;/span&gt;.&lt;span style="color: maroon"&gt;Point &lt;/span&gt;= &lt;span style="color: maroon"&gt;point1&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;.&lt;span style="color: maroon"&gt;Segments&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;seg1&lt;/span&gt;);

    &lt;span style="color: green"&gt;// Use an arc for the circular side
    &lt;/span&gt;&lt;span style="color: #a65300"&gt;ArcSegment &lt;/span&gt;&lt;span style="color: maroon"&gt;seg2 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;ArcSegment&lt;/span&gt;();
    &lt;span style="color: maroon"&gt;seg2&lt;/span&gt;.&lt;span style="color: maroon"&gt;Point &lt;/span&gt;= &lt;span style="color: maroon"&gt;point2&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;seg2&lt;/span&gt;.&lt;span style="color: maroon"&gt;Size &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Size&lt;/span&gt;(&lt;span style="color: maroon"&gt;RadiusX&lt;/span&gt;, &lt;span style="color: maroon"&gt;RadiusY&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;seg2&lt;/span&gt;.&lt;span style="color: maroon"&gt;RotationAngle &lt;/span&gt;= &lt;span style="color: maroon"&gt;SliceCenterAngle&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;seg2&lt;/span&gt;.&lt;span style="color: maroon"&gt;IsLargeArc &lt;/span&gt;= (&lt;span style="color: maroon"&gt;SliceCenterAngle &lt;/span&gt;&amp;gt; &lt;span style="background: #e6ffff"&gt;180.0&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;seg2&lt;/span&gt;.&lt;span style="color: maroon"&gt;SweepDirection &lt;/span&gt;= &lt;span style="color: #2b91af"&gt;SweepDirection&lt;/span&gt;.&lt;span style="color: maroon"&gt;Counterclockwise&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;.&lt;span style="color: maroon"&gt;Segments&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;seg2&lt;/span&gt;);

    &lt;span style="color: green"&gt;// Close shape by going back to the starting point
    &lt;/span&gt;&lt;span style="color: #a65300"&gt;LineSegment &lt;/span&gt;&lt;span style="color: maroon"&gt;seg3 &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;LineSegment&lt;/span&gt;();
    &lt;span style="color: maroon"&gt;seg3&lt;/span&gt;.&lt;span style="color: maroon"&gt;Point &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Point&lt;/span&gt;(&lt;span style="color: maroon"&gt;point0&lt;/span&gt;.&lt;span style="color: maroon"&gt;X&lt;/span&gt;, &lt;span style="color: maroon"&gt;point0&lt;/span&gt;.&lt;span style="color: maroon"&gt;Y&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;.&lt;span style="color: maroon"&gt;Segments&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: maroon"&gt;seg3&lt;/span&gt;);

    &lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;.&lt;span style="color: maroon"&gt;IsClosed &lt;/span&gt;= &lt;span style="color: navy"&gt;true&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;.&lt;span style="color: maroon"&gt;IsFilled &lt;/span&gt;= &lt;span style="color: navy"&gt;true&lt;/span&gt;;

    &lt;span style="color: navy"&gt;return &lt;/span&gt;&lt;span style="color: maroon"&gt;pathFigure&lt;/span&gt;;
}

&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Returns a point on the ellipse based on the rotationAngle, using
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;RadiusX/Y as the center (0, 0).
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color: navy"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Point &lt;/span&gt;&lt;span style="color: maroon"&gt;CalculatePointOnEllipse&lt;/span&gt;(&lt;span style="color: navy"&gt;double &lt;/span&gt;&lt;span style="color: maroon"&gt;rotationAngle&lt;/span&gt;)
{
    &lt;span style="color: navy"&gt;double &lt;/span&gt;&lt;span style="color: maroon"&gt;angleRadians &lt;/span&gt;= &lt;span style="color: maroon"&gt;rotationAngle &lt;/span&gt;* &lt;span style="color: #a65300"&gt;Math&lt;/span&gt;.&lt;span style="color: maroon"&gt;PI &lt;/span&gt;/ &lt;span style="background: #e6ffff"&gt;180.0&lt;/span&gt;;
    &lt;span style="color: navy"&gt;double &lt;/span&gt;&lt;span style="color: maroon"&gt;x &lt;/span&gt;= &lt;span style="color: #a65300"&gt;Math&lt;/span&gt;.&lt;span style="color: maroon"&gt;Cos&lt;/span&gt;(&lt;span style="color: maroon"&gt;angleRadians&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;x &lt;/span&gt;= &lt;span style="color: maroon"&gt;RadiusX &lt;/span&gt;* &lt;span style="color: maroon"&gt;x&lt;/span&gt;;
    &lt;span style="color: navy"&gt;double &lt;/span&gt;&lt;span style="color: maroon"&gt;y &lt;/span&gt;= &lt;span style="color: #a65300"&gt;Math&lt;/span&gt;.&lt;span style="color: maroon"&gt;Sin&lt;/span&gt;(&lt;span style="color: maroon"&gt;angleRadians&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;y &lt;/span&gt;= &lt;span style="color: maroon"&gt;RadiusY &lt;/span&gt;* &lt;span style="color: maroon"&gt;y&lt;/span&gt;;

    &lt;span style="color: #2b91af"&gt;Point &lt;/span&gt;&lt;span style="color: maroon"&gt;result &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Point&lt;/span&gt;(&lt;span style="color: maroon"&gt;x&lt;/span&gt;, &lt;span style="color: maroon"&gt;y&lt;/span&gt;);
    &lt;span style="color: maroon"&gt;result&lt;/span&gt;.&lt;span style="color: maroon"&gt;X &lt;/span&gt;= &lt;span style="color: maroon"&gt;RadiusX &lt;/span&gt;- &lt;span style="color: maroon"&gt;x&lt;/span&gt;;
    &lt;span style="color: maroon"&gt;result&lt;/span&gt;.&lt;span style="color: maroon"&gt;Y &lt;/span&gt;= &lt;span style="color: maroon"&gt;RadiusY &lt;/span&gt;+ &lt;span style="color: maroon"&gt;y&lt;/span&gt;;
    &lt;span style="color: navy"&gt;return &lt;/span&gt;&lt;span style="color: maroon"&gt;result&lt;/span&gt;;
}
&lt;/pre&gt;
&lt;h4&gt;Step 4: Going Forward&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/SpinningWaitSymbolinSilverlightPart2_96B0/SpinningCursor1-TestPage_1.png"&gt;&lt;img height="181" alt="SpinningCursor1-TestPage" src="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/SpinningWaitSymbolinSilverlightPart2_96B0/SpinningCursor1-TestPage_thumb_1.png" width="240" align="right" /&gt;&lt;/a&gt; Obviously this still needs a lot of improvement before it approaches the appeal of the Marble of Doom, which I will work on in the coming posts. However, the initial effort to create the "pizza" slices has been achieved and it is easier to build upon a base.&lt;/p&gt;
&lt;p&gt;I added a grid in the background when I had some difficulty with the path geometry, but it is useful to I added two text boxes for the number of slices and rotation angle so that I could see the shape update dynamically.&lt;/p&gt;
&lt;p&gt;Since I just used LineSegments to connect the slice points, the shape does not have the swirl or twist effect yet. Next time I will add the twist as well as rotation.&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:f5e14260-1dfe-4501-958f-a487a74b5e5d" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/C#" rel="tag"&gt;C#&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.nimblecoder.com%2fblog%2farchive%2f2008%2f10%2f20%2fspinning-wait-symbol-in-silverlight-part-2.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.nimblecoder.com%2fblog%2farchive%2f2008%2f10%2f20%2fspinning-wait-symbol-in-silverlight-part-2.aspx" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/73.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=POMBlMrRYq8:KAqnpqdlC58:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=POMBlMrRYq8:KAqnpqdlC58:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=POMBlMrRYq8:KAqnpqdlC58:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=POMBlMrRYq8:KAqnpqdlC58:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=POMBlMrRYq8:KAqnpqdlC58:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/10/20/spinning-wait-symbol-in-silverlight-part-2.aspx</guid>
            <pubDate>Mon, 20 Oct 2008 20:08:58 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/73.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/10/20/spinning-wait-symbol-in-silverlight-part-2.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/73.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/73.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/10/20/spinning-wait-symbol-in-silverlight-part-2.aspx</feedburner:origLink></item>
        <item>
            <title>Spinning Wait Symbol in Silverlight</title>
            <category>C#</category>
            <category>SilverLight</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/P5T17RVcZEk/spinning-wait-symbol-in-silverlight.aspx</link>
            <description>&lt;ul&gt; &lt;li&gt;Download: &lt;a href="/blog/Samples/Silverlight/RotatingHourGlass.zip"&gt;RotatingHourGlass&lt;/a&gt; VS2008 Source/Silverlight beta 2 (503 KB)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;My wife has a Treo with Windows Mobile and I when I was using it I noticed it had a cool rotating wait symbol, so I wondered how difficult it would be to build the symbol in &lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt;. The symbol is similar to the old &lt;a href="http://en.wikipedia.org/wiki/Beos"&gt;BeOS&lt;/a&gt; wait cursor and has as well as the &lt;a href="http://en.wikipedia.org/wiki/Spinning_wait_cursor_(Mac_OS_X)"&gt;Mac OS X wait cursor&lt;/a&gt; which I've always thought looks nice. At one point in time I created a Windows cursor that duplicated the look of the BeOS cursor but I don't use it anymore. If I found a really nice looking 24-bit cursor then I might use it again.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/CircularRotatingWaitSymbolinSilverlight_C269/Quadrant1.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="172" alt="Quadrant1" src="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/CircularRotatingWaitSymbolinSilverlight_C269/Quadrant1_thumb_3.png" width="177" align="right" border="0" /&gt;&lt;/a&gt;The first step is to create the four quadrants. I used the path geometry to create each quadrant, for example the first quadrant is: &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: red"&gt;Data&lt;/span&gt;&lt;span style="color: blue"&gt;="M0,0 C0,0 100,0 100,100 L0,100 z"&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;For reference , the &lt;a title="Path Markup Syntax" href="http://msdn.microsoft.com/en-us/library/ms752293.aspx"&gt;path markup syntax&lt;/a&gt; is documented at MSDN. The shape starts at (0,0) and creates a curve point with a control point at (100,0) and end point at (100,100). Then there is a LineTo (0,100) and finally the close ("z") marker to complete the shape. While this is fairly easy through a graphical editor such as &lt;a href="http://www.microsoft.com/expression/"&gt;Expression Blend&lt;/a&gt; (&lt;a href="http://blogs.msdn.com/expression/default.aspx"&gt;blog&lt;/a&gt;), I created this manually so that I could have more control over the exact coordinates rather than relying on the graphical editor.&lt;/p&gt;
&lt;p&gt;I repeated the shape for each quadrant by adjusting the coordinates as necessary. It is also possible to simply apply a rotation to the shape so you have rotations of 90, 180, and 270 degrees, but remember to set the RenderTransformOrigin to the correct corner such as (0,1) to rotate by the bottom left corner.&lt;/p&gt;
&lt;p&gt;Once the quadrants are built, then I placed a rotating quadrant named 'Spinner' over the combined shape. I used an alpha mask on the spinner to differentiate it from the other quadrants. Finally, I added a Storyboard to rotate the 'Spinner' 360 degrees every two seconds:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Storyboard &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;="SpinStoryboard" &lt;/span&gt;&lt;span style="color: red"&gt;RepeatBehavior&lt;/span&gt;&lt;span style="color: blue"&gt;="Forever"&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;  &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;DoubleAnimationUsingKeyFrames &lt;/span&gt;&lt;span style="color: red"&gt;BeginTime&lt;/span&gt;&lt;span style="color: blue"&gt;="00:00:00" &lt;/span&gt;&lt;span style="color: red"&gt;Storyboard.TargetName&lt;/span&gt;&lt;span style="color: blue"&gt;="Spinner"
      &lt;/span&gt;&lt;span style="color: red"&gt;Storyboard.TargetProperty&lt;/span&gt;&lt;span style="color: blue"&gt;="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;    &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;SplineDoubleKeyFrame &lt;/span&gt;&lt;span style="color: red"&gt;KeyTime&lt;/span&gt;&lt;span style="color: blue"&gt;="00:00:02" &lt;/span&gt;&lt;span style="color: red"&gt;Value&lt;/span&gt;&lt;span style="color: blue"&gt;="360"/&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffffe6"&gt;  &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;DoubleAnimationUsingKeyFrames&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Storyboard&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The end result is a nice looking animation that is fairly simple. I'm tempted to try to duplicate the Mac OS X wait cursor, but that will have to wait until I have more time.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/CircularRotatingWaitSymbolinSilverlight_C269/SpinningCursorBlend.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="Spinning Cursor in Blend" src="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/CircularRotatingWaitSymbolinSilverlight_C269/SpinningCursorBlend_thumb.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.nimblecoder.com%2fblog%2farchive%2f2008%2f10%2f08%2fspinning-wait-symbol-in-silverlight.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.nimblecoder.com%2fblog%2farchive%2f2008%2f10%2f08%2fspinning-wait-symbol-in-silverlight.aspx" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:15bb7f99-5d4f-4383-a8b5-f79f539a6bd1" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;&lt;/div&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/72.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=P5T17RVcZEk:tTo616Dh230:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=P5T17RVcZEk:tTo616Dh230:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=P5T17RVcZEk:tTo616Dh230:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=P5T17RVcZEk:tTo616Dh230:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=P5T17RVcZEk:tTo616Dh230:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/10/08/spinning-wait-symbol-in-silverlight.aspx</guid>
            <pubDate>Wed, 08 Oct 2008 13:03:49 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/72.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/10/08/spinning-wait-symbol-in-silverlight.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/72.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/72.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/10/08/spinning-wait-symbol-in-silverlight.aspx</feedburner:origLink></item>
        <item>
            <title>Bouncing Balls in Silverlight Part 1</title>
            <category>C#</category>
            <category>SilverLight</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/X6w2vFapfjI/bouncing-balls-in-silverlight-part-1.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/SimpleBouncingBallinSilverlight_13872/BounceTest.png" rel="lightbox"&gt;&lt;img height="200" alt="BounceTest" src="http://www.nimblecoder.com/blog/Images/nimblecoder_com/blog/WindowsLiveWriter/SimpleBouncingBallinSilverlight_13872/BounceTest_thumb_3.png" width="240" align="right" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="/blog/Samples/Silverlight/BounceTest1.zip"&gt;BounceTest1&lt;/a&gt; (104 KB): Source (VS2008) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Recently I wanted to make a very simple sample in &lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt; that used a little code to animate bouncing balls. The overall effect is fairly simple, but getting the sample down to the basics took a little time. As part of my research, I looked at several old bouncing ball demos using JavaScript and it was an eye-opening reminder of the dark ages of browsers and JavaScript.&lt;/p&gt;  &lt;p&gt;For the sample, I wanted to keep everything very simple. I started with a circle (ellipse with the same height and width) in a canvas. In order to move the ball, I chose to position the ball at (0, 0) and use a TranslateTransform to adjust the position. You could easily move the ball around with Left and Top, but I also plan to use RotateTransform in later samples so it makes sense to use a TransformGroup to manipulate the object.&lt;/p&gt;  &lt;p&gt;The XAML for the base page is just a Canvas and a rectangle that acts as a border. The ball is placed on the canvas using the common TransformGroup that is created by Expression Blend when you add a transform to an object. Expression Blend also uses the same order for the transforms (ScaleTransform, SkewTransform, RotateTransform, TranslateTransform) and will reorder the transforms back to this order if you adjust any transform using Blend (at least as of Blend 2.5 June 2008 Preview). Here is the XAML for the page:&lt;/p&gt;  &lt;pre class="xml" name="code"&gt;&amp;lt;UserControl x:Class="BounceTest.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300"&amp;gt;
    &amp;lt;Canvas x:Name="LayoutRoot"&amp;gt;
        &amp;lt;Rectangle x:Name="Boundary" Height="300" Width="400" 
            Canvas.Left="0" Canvas.Top="0"
            Fill="#FFFFFFFF" Stroke="#FF000000" /&amp;gt;
        &amp;lt;Ellipse x:Name="Ball01" Height="25" Width="25"
            Canvas.Left="0" Canvas.Top="0"
            Fill="#FFEE3131" Stroke="#FF000000"
            RenderTransformOrigin="0.5,0.5"&amp;gt;
            &amp;lt;Ellipse.RenderTransform&amp;gt;
                &amp;lt;TransformGroup&amp;gt;
                    &amp;lt;ScaleTransform/&amp;gt;
                    &amp;lt;SkewTransform/&amp;gt;
                    &amp;lt;RotateTransform/&amp;gt;
                    &amp;lt;TranslateTransform X="50" Y="50"/&amp;gt;
                &amp;lt;/TransformGroup&amp;gt;
            &amp;lt;/Ellipse.RenderTransform&amp;gt;
        &amp;lt;/Ellipse&amp;gt;
    &amp;lt;/Canvas&amp;gt;
&amp;lt;/UserControl&amp;gt;&lt;/pre&gt;

&lt;p&gt;I created a small class to manage the position and velocity of the ball. The constructor takes the source shape (the ball), the velocity, and the boundary shape. For this scenario, I assume that the ball already has the RotateTransform otherwise it throws an exception. The code could easily create a RotateTransform if it isn't present. The Update method takes the elapsed time since the previous method call. The boundary checking is extremely simple and just changes the direction of the motion when the ball hits a boundary edge. This obviously needs a lot of work for more complex scenarios, but it will do for this simple case.&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public class ShapeVelocity
{
	public Shape shape;
	public Vector velocity;
	public TranslateTransform translate;
	public Size bounds;
	public Size container;

	public ShapeVelocity(Shape AShape, Vector AVelocity, Shape BoundsContainer)
	{
		this.shape = AShape;
		this.velocity = AVelocity;

		var renderTransform = this.shape.RenderTransform;
		if (renderTransform is TransformGroup)
		{
			TransformGroup transformGroup = (TransformGroup)renderTransform;
			foreach (Transform transform in transformGroup.Children)
				if (transform is TranslateTransform)
					this.translate = (TranslateTransform)transform;
		}
		if (this.translate == null)
			throw new ArgumentException("Shape must have a TranslateTransform in it");

		container = new Size(BoundsContainer.Width, BoundsContainer.Height);
		bounds = new Size(
			this.shape.ActualWidth + this.shape.StrokeThickness,
			this.shape.ActualHeight + this.shape.StrokeThickness);
	}

	public void Update(TimeSpan Interval)
	{
		Rect pos = new Rect(
			translate.X,
			translate.Y,
			bounds.Width,
			bounds.Height);

		if ((velocity.X &amp;lt; 0.0) &amp;amp;&amp;amp; (pos.Left &amp;lt; 0.0))
			velocity.X = -velocity.X;
		else if ((velocity.X &amp;gt; 0.0) &amp;amp;&amp;amp; (pos.Right &amp;gt; container.Width))
			velocity.X = -velocity.X;
		if ((velocity.Y &amp;lt; 0.0) &amp;amp;&amp;amp; (pos.Top &amp;lt; 0.0))
			velocity.Y = -velocity.Y;
		else if ((velocity.Y &amp;gt; 0.0) &amp;amp;&amp;amp; (pos.Bottom &amp;gt; container.Height))
			velocity.Y = -velocity.Y;

		translate.X += velocity.X * (double) Interval.Milliseconds / 1000.0;
		translate.Y += velocity.Y * (double) Interval.Milliseconds / 1000.0;
	}
}&lt;/pre&gt;

&lt;p&gt;In anticipation of future examples, I used a List&amp;lt;Shape&amp;gt; collection to store the ball shape to updae the position. For the motion, I used the StoryBoard instead of a DispatcherTimer based on the &lt;a title="Procedural Animation in Silverlight 2" href="http://adamkinney.com/blog/339/default.aspx"&gt;recommendation&lt;/a&gt; of &lt;a href="http://adamkinney.com/"&gt;Adam Kinney&lt;/a&gt;.&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public partial class Page : UserControl
{
    private DateTime _lastTime = DateTime.MinValue;
    private double _initialSpeed = 50.0;
    private Storyboard _storyboard;
    private List&amp;lt;ShapeVelocity&amp;gt; _shapes;

    public Page()
    {
        InitializeComponent();
        _shapes = new List&amp;lt;ShapeVelocity&amp;gt;();
        _storyboard = new Storyboard();
        _storyboard.Duration = TimeSpan.FromMilliseconds(10);
        _storyboard.Completed += new EventHandler(storyboard_Tick);
        this.Loaded += new RoutedEventHandler(Page_Loaded);
    }

    void Page_Loaded(object sender, RoutedEventArgs e)
    {
        _shapes.Add(new ShapeVelocity(Ball01, new Vector(_initialSpeed, _initialSpeed), Boundary));
        _lastTime = System.DateTime.Now;
        _storyboard.Begin();
    }

    void storyboard_Tick(object sender, EventArgs e)
    {
        DateTime now = System.DateTime.Now;
        TimeSpan interval = now - _lastTime;
        foreach (ShapeVelocity s in _shapes)
        {
            s.Update(interval);
        }
        _lastTime = now;
        _storyboard.Begin();
    }
}&lt;/pre&gt;

&lt;p&gt;So that is the very simple bouncing ball sample.&lt;/p&gt;

&lt;div id="silverlightControlHost"&gt;&lt;object data="data:application/x-silverlight," type="application/x-silverlight-2-b2" width="400px" height="300px"&gt;
    &lt;param name="source" value="ClientBin/BounceTest1.xap" /&gt;
    &lt;param name="background" value="white" /&gt;

    &lt;a href="http://go.microsoft.com/fwlink/?LinkID=115261" style="text-decoration: none;"&gt;
      &lt;img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none" /&gt;
    &lt;/a&gt;
  &lt;/object&gt;&lt;iframe style="border-top-width: 0px; border-left-width: 0px; visibility: hidden; border-bottom-width: 0px; width: 0px; height: 0px; border-right-width: 0px" /&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.nimblecoder.com%2fblog%2farchive%2f2008%2f09%2f14%2fbouncing-balls-in-silverlight-part-1.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.nimblecoder.com%2fblog%2farchive%2f2008%2f09%2f14%2fbouncing-balls-in-silverlight-part-1.aspx" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4f75fff4-67d0-445c-aaea-3d26857c8525" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/C%23" rel="tag"&gt;C#&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;&lt;/div&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/71.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=X6w2vFapfjI:zlwGy3yjoY4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=X6w2vFapfjI:zlwGy3yjoY4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=X6w2vFapfjI:zlwGy3yjoY4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=X6w2vFapfjI:zlwGy3yjoY4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=X6w2vFapfjI:zlwGy3yjoY4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/09/14/bouncing-balls-in-silverlight-part-1.aspx</guid>
            <pubDate>Mon, 15 Sep 2008 04:28:30 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/71.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/09/14/bouncing-balls-in-silverlight-part-1.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/71.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/71.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/09/14/bouncing-balls-in-silverlight-part-1.aspx</feedburner:origLink></item>
        <item>
            <title>Constant Prototyping and Design</title>
            <category>JavaScript</category>
            <category>Programming</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/WQFlat-KhL0/constant-prototyping-and-design.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/ConstantPrototypingandDesign_885D/BalletDancer_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" alt="Ballet" src="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/ConstantPrototypingandDesign_885D/BalletDancer_thumb.png" width="188" align="left" border="0" /&gt;&lt;/a&gt;A co-worker gave a presentation on a project we worked on a long time ago and he asked me to update an feature in the web application. The web app was originally programmed in ASP and I had almost forgotten how painful it was to work in that environment. The new request was to enable live presence information in a web part using the new &lt;a href="http://msdn.microsoft.com/en-us/library/ms931946.aspx" target="_blank"&gt;RTC&lt;/a&gt; libraries. Fortunately, another developer had a component to perform all of the calls using the RTC libraries, but I needed to retrieve the group members for the selected group and cross-reference the group members with online presence.&lt;/p&gt; &lt;p&gt;The actual details involved opening "MTSAdmin.Catalog.1" object and looking for a specific COM+ package, enumerating the "RolesInPackage", and then getting the "UsersInRole". There were several layers of filtering going on and I wanted an elegant solution. Unfortunately I kept trying to be too elegant and I was getting hung up on how to make it more elegant. I wanted to have a "before", "item", and "after" callback functions at each of the function depth levels where the "item" function would occur in the iteration loop. This would allow for scenarios where items might need to be collected after iteration, particularly to avoid making multiple unnecessary calls to the lower filtering methods.&lt;/p&gt; &lt;h3&gt;Small example from jQuery&lt;/h3&gt;&lt;pre class="js" name="code"&gt;ajax: function( s ) {
  &lt;span class="rem"&gt;// Extend the settings, but re-extend 's' so that it can be&lt;/span&gt;
  &lt;span class="rem"&gt;// checked again later (in the test suite, specifically)&lt;/span&gt;
  s = jQuery.extend(&lt;span class="kwrd"&gt;true&lt;/span&gt;, s, jQuery.extend(&lt;span class="kwrd"&gt;true&lt;/span&gt;, {}, jQuery.ajaxSettings, s));

  &lt;span class="rem"&gt;// ... snip, snip, snip ...&lt;/span&gt;

  &lt;span class="rem"&gt;// Allow custom headers/mimetypes&lt;/span&gt;
  &lt;span class="kwrd"&gt;if&lt;/span&gt; ( s.beforeSend &amp;amp;&amp;amp; s.beforeSend(xhr, s) === &lt;span class="kwrd"&gt;false&lt;/span&gt; ) {
    &lt;span class="rem"&gt;// cleanup active request counter&lt;/span&gt;
    s.global &amp;amp;&amp;amp; jQuery.active--;
    &lt;span class="rem"&gt;// close opended socket&lt;/span&gt;
    xhr.abort();
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
  }
&lt;/pre&gt;
&lt;p&gt;The example above from jQuery only uses the "before" concept that I mentioned above, but it shows a very nice implementation where the 's' object is based on jQuery.ajaxSettings. Just before the AJAX call is about to be made, jQuery checks for any custom headers and calls the 'beforeSend' function if it exists.&lt;/p&gt;
&lt;h3&gt;Start Simple and Add Progressive Elegance&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ableman/234145236/"&gt;&lt;img height="160" alt="BaseballHomerun" src="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/ConstantPrototypingandDesign_885D/BaseballHomerun_3.jpg" width="240" align="right" border="0" /&gt;&lt;/a&gt; I did manage to get the function working correctly, but I had to take a step back and start simple and progressively build additional functionality into the component. Sometimes you have inspiration and you can just design and code and everything is great. Other times it can take a while before the inspiration comes. It is better to start coding and have something you can refine rather than wait and lose valuable time.&lt;/p&gt;
&lt;p&gt;To use a baseball analogy: Don't try to hit a homerun every time; sometimes you need to play "&lt;a href="http://en.wikipedia.org/wiki/Small_Ball"&gt;small ball&lt;/a&gt;" and get people in scoring position and just try to make contact. A similar soccer (futból!) analogy would be don't just try to dribble down the field and score every time, but you need to pass and set up the players around you to maximize the scoring opportunity.&lt;/p&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/70.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=WQFlat-KhL0:DZc2WcdmYzA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=WQFlat-KhL0:DZc2WcdmYzA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=WQFlat-KhL0:DZc2WcdmYzA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=WQFlat-KhL0:DZc2WcdmYzA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=WQFlat-KhL0:DZc2WcdmYzA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/07/31/constant-prototyping-and-design.aspx</guid>
            <pubDate>Thu, 31 Jul 2008 16:28:32 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/70.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/07/31/constant-prototyping-and-design.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/70.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/70.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/07/31/constant-prototyping-and-design.aspx</feedburner:origLink></item>
        <item>
            <title>On Sample Simplicity</title>
            <category>C#</category>
            <category>LINQ</category>
            <category>Programming</category>
            <category>SilverLight</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/4bWT8KyBWuU/on-sample-simplicity.aspx</link>
            <description>&lt;p&gt;I was working through a Communications sample of connecting &lt;a href="http://silverlight.net/" target="_blank"&gt;SilverLight&lt;/a&gt; to &lt;a href="http://en.wikipedia.org/wiki/Plain_Old_XML" target="_blank"&gt;POX&lt;/a&gt;, then &lt;a href="http://en.wikipedia.org/wiki/Web_services" target="_blank"&gt;Web Services&lt;/a&gt;, and finally &lt;a href="http://msdn.microsoft.com/en-us/library/ms735119.aspx" target="_blank"&gt;WCF&lt;/a&gt; and I came across the following instructions:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;(Part 1: POX) The Generic handler will process an incoming request using the code declared in the &lt;em&gt;ProcessRequest&lt;/em&gt; function. This function should create some new instances of CityData and add them to the myCities list. Here are some examples of cities with longitude and latitude { (London, 51.5, 0), (Stratford-upon-Avon, 52.3, -1.71), (Edinburgh, 55.95, -3.16) }. See if you can write the code to do this.&lt;/p&gt; &lt;p&gt;(And later in the lab...)&lt;/p&gt; &lt;p&gt;In this example your ASHX served up hard-coded data for 1 city. Can you build it so that it can accept parameters on the URI string (i.e. http://localhost:8001/Sample1Web/GetData.ashx?city=whatever)?&lt;/p&gt; &lt;p&gt;(And even further in the lab...)&lt;/p&gt; &lt;p&gt;Write a function that takes in a country and builds a List&amp;lt;CityData&amp;gt; of several cities for that country. Here are some cities and their latitudes and longitudes:&lt;/p&gt;&lt;pre class="code"&gt;(&lt;span style="background: #ffffe6"&gt;"Paris"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;48.87&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;2.33&lt;/span&gt;);
(&lt;span style="background: #ffffe6"&gt;"Lourdes"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;43.1&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0.05&lt;/span&gt;);
(&lt;span style="background: #ffffe6"&gt;"Toulouse"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;43.6&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;1.38&lt;/span&gt;);
(&lt;span style="background: #ffffe6"&gt;"London"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;51.5&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;);
(&lt;span style="background: #ffffe6"&gt;"Stratford-Upon-Avon"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;52.3&lt;/span&gt;, -&lt;span style="background: #e6ffff"&gt;1.71&lt;/span&gt;);
(&lt;span style="background: #ffffe6"&gt;"Edinburgh"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;55.95&lt;/span&gt;, -&lt;span style="background: #e6ffff"&gt;3.16&lt;/span&gt;);
(&lt;span style="background: #ffffe6"&gt;"Berlin"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;52.52&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;13.42&lt;/span&gt;);
(&lt;span style="background: #ffffe6"&gt;"Munich"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;48.13&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;11.57&lt;/span&gt;);
(&lt;span style="background: #ffffe6"&gt;"Hamburg"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;53.58&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;9.98&lt;/span&gt;);&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;
&lt;h3&gt;Provided Solution&lt;/h3&gt;
&lt;p&gt;The sample provided "solution" code at the end of the instructions. The code is basic and unimaginative, but perhaps that is all the is needed of sample code (I would offer that samples are the perfect to push the boundaries -- lead by example).&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// File: CityData.cs
&lt;/span&gt;&lt;span style="color: navy"&gt;public class &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData
&lt;/span&gt;{
    &lt;span style="color: navy"&gt;public string &lt;/span&gt;&lt;span style="color: maroon"&gt;CityName &lt;/span&gt;{ &lt;span style="color: navy"&gt;get&lt;/span&gt;; &lt;span style="color: navy"&gt;set&lt;/span&gt;; }
    &lt;span style="color: navy"&gt;public double &lt;/span&gt;&lt;span style="color: maroon"&gt;Latitude &lt;/span&gt;{ &lt;span style="color: navy"&gt;get&lt;/span&gt;; &lt;span style="color: navy"&gt;set&lt;/span&gt;; }
    &lt;span style="color: navy"&gt;public double &lt;/span&gt;&lt;span style="color: maroon"&gt;Longitude &lt;/span&gt;{ &lt;span style="color: navy"&gt;get&lt;/span&gt;; &lt;span style="color: navy"&gt;set&lt;/span&gt;; }

    &lt;span style="color: navy"&gt;public &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="color: navy"&gt;string &lt;/span&gt;&lt;span style="color: maroon"&gt;strCityName&lt;/span&gt;, &lt;span style="color: navy"&gt;double &lt;/span&gt;&lt;span style="color: maroon"&gt;nLatitude&lt;/span&gt;, &lt;span style="color: navy"&gt;double &lt;/span&gt;&lt;span style="color: maroon"&gt;nLongitude&lt;/span&gt;)
    {
        &lt;span style="color: maroon"&gt;CityName &lt;/span&gt;= &lt;span style="color: maroon"&gt;strCityName&lt;/span&gt;;
        &lt;span style="color: maroon"&gt;Latitude &lt;/span&gt;= &lt;span style="color: maroon"&gt;nLatitude&lt;/span&gt;;
        &lt;span style="color: maroon"&gt;Longitude &lt;/span&gt;= &lt;span style="color: maroon"&gt;nLongitude&lt;/span&gt;;
    }

    &lt;span style="color: navy"&gt;public &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;()
    {
    }
}

&lt;span style="color: green"&gt;// File: GetData.ashx
&lt;/span&gt;&lt;span style="color: navy"&gt;public class &lt;/span&gt;&lt;span style="color: maroon"&gt;GetData &lt;/span&gt;: &lt;span style="color: maroon"&gt;IHttpHandler
&lt;/span&gt;{
    &lt;span style="color: navy"&gt;private &lt;/span&gt;&lt;span style="color: maroon"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt; &lt;span style="color: maroon"&gt;getCities&lt;/span&gt;(&lt;span style="color: navy"&gt;string &lt;/span&gt;&lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;)
    {
        &lt;span style="color: maroon"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt; &lt;span style="color: maroon"&gt;ret &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt;();

        &lt;span style="color: navy"&gt;switch &lt;/span&gt;(&lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;)
        {
        &lt;span style="color: navy"&gt;case &lt;/span&gt;&lt;span style="background: #ffffe6"&gt;"france"&lt;/span&gt;:
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Paris"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;48.87&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;2.33&lt;/span&gt;));
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Lourdes"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;43.1&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0.05&lt;/span&gt;));
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Toulouse"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;43.6&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;1.38&lt;/span&gt;));
            &lt;span style="color: navy"&gt;break&lt;/span&gt;;

        &lt;span style="color: navy"&gt;case &lt;/span&gt;&lt;span style="background: #ffffe6"&gt;"uk"&lt;/span&gt;:
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"London"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;51.5&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;));
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Stratford-Upon-Avon"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;52.3&lt;/span&gt;, -&lt;span style="background: #e6ffff"&gt;1.71&lt;/span&gt;));
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Edinburgh"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;55.95&lt;/span&gt;, -&lt;span style="background: #e6ffff"&gt;3.16&lt;/span&gt;));
            &lt;span style="color: navy"&gt;break&lt;/span&gt;;

        &lt;span style="color: navy"&gt;case &lt;/span&gt;&lt;span style="background: #ffffe6"&gt;"germany"&lt;/span&gt;:
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Berlin"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;52.52&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;13.42&lt;/span&gt;));
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Munich"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;48.13&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;11.57&lt;/span&gt;));
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Hamburg"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;53.58&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;9.98&lt;/span&gt;));
            &lt;span style="color: navy"&gt;break&lt;/span&gt;;

        &lt;span style="color: navy"&gt;default&lt;/span&gt;:
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"London"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;51.5&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;));
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Stratford-Upon-Avon"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;52.3&lt;/span&gt;, -&lt;span style="background: #e6ffff"&gt;1.71&lt;/span&gt;));
            &lt;span style="color: maroon"&gt;ret&lt;/span&gt;.&lt;span style="color: maroon"&gt;Add&lt;/span&gt;(&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Edinburgh"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;55.95&lt;/span&gt;, -&lt;span style="background: #e6ffff"&gt;3.16&lt;/span&gt;));
            &lt;span style="color: navy"&gt;break&lt;/span&gt;;
        }
        &lt;span style="color: navy"&gt;return &lt;/span&gt;&lt;span style="color: maroon"&gt;ret&lt;/span&gt;;
    }
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;h3&gt;Alternative 1&lt;/h3&gt;
&lt;p&gt;I wanted to explore alternatives to the supplied code, so I decided to initialize the CityData list with the data instead of using "Add". In C++ this was more efficient (it set the initial list size instead of using the default capacity sizing algorithm among other things), but I'm not sure of performance in terms of C#. I would not expect any significant performance difference with this small sample though.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: navy"&gt;public &lt;/span&gt;&lt;span style="color: maroon"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt; &lt;span style="color: maroon"&gt;getCities&lt;/span&gt;(&lt;span style="color: navy"&gt;string &lt;/span&gt;&lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;)
{
    &lt;span style="color: maroon"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt; &lt;span style="color: maroon"&gt;ret &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt;();

    &lt;span style="color: navy"&gt;switch &lt;/span&gt;( &lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;.&lt;span style="color: maroon"&gt;ToLower&lt;/span&gt;() )
    {
        &lt;span style="color: navy"&gt;case &lt;/span&gt;&lt;span style="background: #ffffe6"&gt;"france"&lt;/span&gt;:
            &lt;span style="color: maroon"&gt;ret &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt;() {
                &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Paris"&lt;/span&gt;, &lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;48.87&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;2.33&lt;/span&gt;),
                &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Lourdes"&lt;/span&gt;, &lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;43.1&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0.05&lt;/span&gt;),
                &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Toulouse"&lt;/span&gt;, &lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;43.6&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;1.38&lt;/span&gt;)
            };
            &lt;span style="color: navy"&gt;break&lt;/span&gt;;

        &lt;span style="color: navy"&gt;case &lt;/span&gt;&lt;span style="background: #ffffe6"&gt;"germany"&lt;/span&gt;:
            &lt;span style="color: maroon"&gt;ret &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt;() {
                &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Berlin"&lt;/span&gt;, &lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;52.52&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;13.42&lt;/span&gt;),
                &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Munich"&lt;/span&gt;, &lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;48.13&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;11.57&lt;/span&gt;),
                &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Hamburg"&lt;/span&gt;, &lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;53.58&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;9.98&lt;/span&gt;)
            };
            &lt;span style="color: navy"&gt;break&lt;/span&gt;;

        &lt;span style="color: navy"&gt;case &lt;/span&gt;&lt;span style="background: #ffffe6"&gt;"uk"&lt;/span&gt;:
        &lt;span style="color: navy"&gt;default&lt;/span&gt;:
            &lt;span style="color: maroon"&gt;strCountry &lt;/span&gt;= &lt;span style="background: #ffffe6"&gt;"UK"&lt;/span&gt;;
            &lt;span style="color: maroon"&gt;ret &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt;() {
                &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"London"&lt;/span&gt;, &lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;51.5&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0&lt;/span&gt;),
                &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Stratford-Upon-Avon"&lt;/span&gt;, &lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;52.3&lt;/span&gt;, -&lt;span style="background: #e6ffff"&gt;1.71&lt;/span&gt;),
                &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Edinburgh"&lt;/span&gt;, &lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;55.95&lt;/span&gt;, -&lt;span style="background: #e6ffff"&gt;3.16&lt;/span&gt;)
            };
            &lt;span style="color: navy"&gt;break&lt;/span&gt;;
    }
    &lt;span style="color: navy"&gt;return &lt;/span&gt;&lt;span style="color: maroon"&gt;ret&lt;/span&gt;;
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;h3&gt;Alternative 2&lt;/h3&gt;
&lt;p&gt;I haven't worked very much with LINQ, so I wanted to compare the same functionality using LINQ. I added a string "Country" to the CityData class and here is the result:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: navy"&gt;private static &lt;/span&gt;&lt;span style="color: #a65300"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt; &lt;span style="color: maroon"&gt;cityList &lt;/span&gt;= &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: #a65300"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt;()
{
    &lt;span style="color: green"&gt;// UK
    &lt;/span&gt;&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Paris"&lt;/span&gt;, &lt;span style="background: #ffffe6"&gt;"UK"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;48.87&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;2.33&lt;/span&gt;),
    &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Lourdes"&lt;/span&gt;, &lt;span style="background: #ffffe6"&gt;"UK"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;43.1&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0.05&lt;/span&gt;),
    &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Toulouse"&lt;/span&gt;, &lt;span style="background: #ffffe6"&gt;"UK"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;43.6&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;1.38&lt;/span&gt;),

    &lt;span style="color: green"&gt;// France
    &lt;/span&gt;&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Paris"&lt;/span&gt;, &lt;span style="background: #ffffe6"&gt;"France"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;48.87&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;2.33&lt;/span&gt;),
    &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Lourdes"&lt;/span&gt;, &lt;span style="background: #ffffe6"&gt;"France"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;43.1&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;0.05&lt;/span&gt;),
    &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Toulouse"&lt;/span&gt;, &lt;span style="background: #ffffe6"&gt;"France"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;43.6&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;1.38&lt;/span&gt;),

    &lt;span style="color: green"&gt;// Germany
    &lt;/span&gt;&lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Berlin"&lt;/span&gt;, &lt;span style="background: #ffffe6"&gt;"Germany"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;52.52&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;13.42&lt;/span&gt;),
    &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Munich"&lt;/span&gt;, &lt;span style="background: #ffffe6"&gt;"Germany"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;48.13&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;11.57&lt;/span&gt;),
    &lt;span style="color: navy"&gt;new &lt;/span&gt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;(&lt;span style="background: #ffffe6"&gt;"Hamburg"&lt;/span&gt;, &lt;span style="background: #ffffe6"&gt;"Germany"&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;53.58&lt;/span&gt;, &lt;span style="background: #e6ffff"&gt;9.98&lt;/span&gt;)
};

&lt;span style="color: navy"&gt;public &lt;/span&gt;&lt;span style="color: maroon"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt; &lt;span style="color: maroon"&gt;getCities&lt;/span&gt;(&lt;span style="color: navy"&gt;string &lt;/span&gt;&lt;span style="color: maroon"&gt;strCountry&lt;/span&gt;)
{
    &lt;span style="color: maroon"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt; &lt;span style="color: maroon"&gt;data &lt;/span&gt;= &lt;span style="color: maroon"&gt;from city &lt;/span&gt;&lt;span style="color: navy"&gt;in &lt;/span&gt;&lt;span style="color: maroon"&gt;cityList
                                 where city&lt;/span&gt;.&lt;span style="color: maroon"&gt;Country &lt;/span&gt;== &lt;span style="color: maroon"&gt;strCountry
                                 select city&lt;/span&gt;;
    &lt;span style="color: navy"&gt;return new &lt;/span&gt;&lt;span style="color: maroon"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: maroon"&gt;CityData&lt;/span&gt;&amp;gt;(&lt;span style="color: maroon"&gt;data&lt;/span&gt;);
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;This is still not the most efficient or optimal method, but I think it looks nice and is helps introduce LINQ in an understandable manner.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Samples and labs should be simple and yet it is a perfect time to include new technologies and push the boundaries so to speak. One thing I certainly don't want to see in samples are basic programming inefficiencies (things that make you cringe) due to lack of effort by the sample creator. That was not necessarily the case with this sample, but it would have been better to present alternatives such as the examples I listed.&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:673666a2-582b-4be1-983b-acae922063a9" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/C#" rel="tag"&gt;C#&lt;/a&gt;, &lt;a href="http://technorati.com/tags/LINQ" rel="tag"&gt;LINQ&lt;/a&gt;&lt;/div&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/69.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=4bWT8KyBWuU:PWUc0pnjxrI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=4bWT8KyBWuU:PWUc0pnjxrI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=4bWT8KyBWuU:PWUc0pnjxrI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=4bWT8KyBWuU:PWUc0pnjxrI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=4bWT8KyBWuU:PWUc0pnjxrI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/06/13/on-sample-simplicity.aspx</guid>
            <pubDate>Fri, 13 Jun 2008 21:08:44 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/69.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/06/13/on-sample-simplicity.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/69.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/69.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/06/13/on-sample-simplicity.aspx</feedburner:origLink></item>
        <item>
            <title>Macro Guidelines for Excel VBA Beginners</title>
            <category>Excel</category>
            <category>SharePoint</category>
            <category>VB</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/7nVl_Kx0oX4/macro-guidelines-for-excel-vba-beginners.aspx</link>
            <description>&lt;p&gt;     I'm in the process of updating an Excel spreadsheet that is failing when it is running     inside of Internet Explorer. The issue is related to the ActiveSheet and other global     properties having a value of Nothing when the code is assuming they have valid references.     As I am going through this spreadsheet, I am noting a wide variety of programming     deficiencies and inefficiencies. Here is a list of some of the issues encountered:&lt;/p&gt;   &lt;blockquote&gt;     If you run spreadsheets under Internet Explorer, use     &lt;span style="font-weight:bold;"&gt;Application.ThisWorkbook&lt;/span&gt; and to ensure the browser     evaluates the reference correctly.&lt;/blockquote&gt;   &lt;blockquote&gt;     NOTE: This is not an exhaustive list, nor do I claim that the "Better" examples     are the best code example, but rather they are (hopefully) significant improvements     over the "Bad" examples. In many cases, I have kept the design of the bad example     so that you can see the differences however you should strive to completely refactor     the code if possible.&lt;/blockquote&gt;   &lt;ol&gt;     &lt;li&gt;       &lt;h3&gt;         Do not abuse the "With" statement in VBA.&lt;/h3&gt;       Some people like "With" and some people don't and I don't particularly care for       it. In particular, do not use nested "With" statements.       &lt;h4&gt;         Example of Bad Code&lt;/h4&gt;       &lt;pre class="vb" style="background-color: #ffdab9" name="code"&gt;' ... BAD EXAMPLE: DO NOT USE ...
With ActiveSheet
  With TestForm
    ' ...
  End With ' TestForm
End With ' ActiveSheet
' ... BAD EXAMPLE: DO NOT USE ...

&lt;/pre&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;h3&gt;
        Avoid using the "Goto" statement in VBA.&lt;/h3&gt;
      "Goto" is almost always a bad idea and a sign of spaghetti code. There are very few cases were it is appropriate to use it -- very few cases!
      &lt;h4&gt;
        Example of Bad Code&lt;/h4&gt;
      &lt;pre class="vb" style="background-color: #ffdab9" name="code"&gt;' ... BAD EXAMPLE: DO NOT USE ...
For i = iHere To lRealLastRow Step 2
  BuildStr = "A" &amp;amp; i + 1
  Range(BuildStr).Select
  If Range(BuildStr).Value = "---" Then GoTo DoneWithNames
  SelectItemDlg.Items_List.AddItem Range(BuildStr).Text
Next

DoneWithNames:
' ... BAD EXAMPLE: DO NOT USE ...
&lt;/pre&gt;
      &lt;h4&gt;
        Example of Better Code (I still would have designed it differently)&lt;/h4&gt;
      &lt;pre class="vb" name="code"&gt;' ...
Dim MyCell As Range
For i = iHere To lRealLastRow Step 2
  Set MyCell = Cells(i + 1, 1)
  If MyCell.Value = "---" Then
    Exit For
  End If
  SelectItemDlg.Items_List.AddItem MyCell.Text
Next
' ...
&lt;/pre&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;h3&gt;
        Avoid using the name of a Form inside the Form code&lt;/h3&gt;
      The current form is implied in the code. It is not necessary to use the form name to reference controls on the form. If you want to differeniate form controls, you can use the 'Me' keyword such as: Me.Hide
      &lt;h4&gt;
        Example of Bad Code&lt;/h4&gt;
      &lt;pre class="vb" style="background-color: #ffdab9" name="code"&gt;' ... BAD EXAMPLE: DO NOT USE ...
' This example is doubly bad because it uses the form name (ChartConfig)
' both explicitly and in a With statement
If ChartConfig.Variable1.Text = ChartConfig.Variable2.Text Then
    MsgBox "Variable1 cannot be same as Variable2. Please choose another variable type.", vbOKCancel

    'Turn off the Change effect on Variable2.
    changeCasevar = False
    With ChartConfig
        .Variable2.Text = ""
        .Variable2Desc.Text = ""
        .Variable2Uom.Text = ""
    End With
    'Turn back on the Change effect on Variable2.
    changeCasevar = True
    Exit Sub
    '
End If

' ... BAD EXAMPLE: DO NOT USE ...
&lt;/pre&gt;
      &lt;h4&gt;
        Example of Better Code (I still would have designed it differently)&lt;/h4&gt;
      &lt;pre class="vb" name="code"&gt;' ...
If Variable1.Text = Variable2.Text Then
    MsgBox "Variable1 cannot be same as Variable2. Please choose another variable type.", vbOKCancel

    'Turn off the Change effect on Variable2.
    changeCasevar = False

    Variable2.Text = ""
    Variable2Desc.Text = ""
    Variable2Uom.Text = ""

    'Turn back on the Change effect on Variable2.
    changeCasevar = True
    Exit Sub
End If

&lt;/pre&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;h3&gt;
        Use Error Handling and Resume to restore Application.ScreenUpdating&lt;/h3&gt;
      &lt;h4&gt;
        Example of Bad Code&lt;/h4&gt;
      &lt;pre class="vb" style="background-color: #ffdab9" name="code"&gt;' ... BAD EXAMPLE: DO NOT USE ...
' There are quite a few global variables and a pass-by-reference
' boolean that should just be the function return value.
Application.ScreenUpdating = False

iOption = "Single"
x = ChartPicker.Input_Val_Text
Call CheckUserRangeInputsAndOutputs(iOption, OkToChart)
iOption = ""

If OkToChart = True Then
    With ChartConfig
        CreateChartingArrays
    End With
End If

Application.ScreenUpdating = True
' ... BAD EXAMPLE: DO NOT USE ...
  &lt;/pre&gt;
      &lt;h4&gt;
        Example of Better Code (I still would have designed it differently)&lt;/h4&gt;
      &lt;pre class="vb" name="code"&gt;' ...
  On Error GoTo ErrorHandler

  Application.ScreenUpdating = False

  If CheckUserRangeInputsAndOutputs("Single") Then
    ChartConfig.CreateChartingArrays
  End If

Exit_Handler:
  Application.ScreenUpdating = True
  Exit Sub

ErrorHandler:
  MsgBox "Error " &amp;amp; Err.Number &amp;amp; ": " &amp;amp; Err.Description
  Resume Exit_Handler

  &lt;/pre&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;h3&gt;
        Use If, Else If, and Else correctly.&lt;/h3&gt;
      &lt;h4&gt;
        Example of Bad Code&lt;/h4&gt;
      &lt;pre class="vb" style="background-color: #ffdab9" name="code"&gt;' ... BAD EXAMPLE: DO NOT USE ...
If TextBoxMinimum.Text = "" Then
  MsgBox "Must enter Minimum Value before proceeding", vbOK
  Result = False
  Exit Function
End If

If TextBoxMaximum.Text = "" Then
  MsgBox "Must enter Maximum Value before proceeding", vbOK
  Result = False
  Exit Function
End If
' ... BAD EXAMPLE: DO NOT USE ...
&lt;/pre&gt;
      &lt;h4&gt;
        Example of Better Code&lt;/h4&gt;
      &lt;pre class="vb" name="code"&gt;' ...
' For a explicit method, you can directly refer to the controls
Result = False
If Not IsNumeric(TextBoxMinimum.Text) Then
  MsgBox "Must enter Minimum Value before proceeding", vbOK
  TextBoxMinimum.SetFocus
ElseIf Not IsNumeric(TextBoxMaximum.Text) Then
  MsgBox "Must enter Maximum Value before proceeding", vbOK
  TextBoxMaximum.SetFocus
Else
  Result = True
End If

' If you can use a generic method, you can iterate through all of the controls
' There are obviously better ways of doing this, especially with .NET
Dim ValidateControl
Dim ControlList = Array(TextBox1, TextBox2, TextBox3)
For Each ValidateControl In ControlList
  If Input_Val_Text = Null Or Input_Val_Text = "" Then
    MsgBox "Must enter Value in " &amp;amp; ValidateControl.Name &amp;amp; " before proceeding", vbOK
    Result = False
    Exit Function
  End If
Next
&lt;/pre&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;h3&gt;
        Avoid using the ActiveSheet, Range, Cells, and other global variables.&lt;/h3&gt;
      Rather than assuming a position, it is much better to set a variable to the desired
      Workbook, Worksheet, or Range.
      &lt;blockquote&gt;In particular, if there is any chance the spreadsheet might run under a browser,
      use &lt;span style="font-weight:bold;"&gt;Application.ThisWorkbook&lt;/span&gt; to ensure the browser
      evaluates the macro correctly.
      &lt;/blockquote&gt;
      &lt;h4&gt;
        Example of Bad Code&lt;/h4&gt;
      &lt;pre class="vb" style="background-color: #ffdab9" name="code"&gt;' ... BAD EXAMPLE: DO NOT USE ...
'NOTE: Arrays start with 1st position as "0", not "1"
'Thus ColLtrs(0) is not used but placed there as a spacer for letter to column alignment:
ColLtrs = Array("", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z")

With ActiveSheet
  Range(ColLtrs(iOutCol) &amp;amp; iOutRow).Select
    
  If UnitSystem = "Metric" Then
    iRow = ActiveCell.Row
    For i = iRow To iLastRow - 1
      currCell = ColLtrs(ActiveCell.Column) &amp;amp; i + 1

      If Range(currCell).Value &amp;lt;&amp;gt; "" Then
        'capture the value from original calculatated data
        Range(currCell).Select

        strOrigValueCell = ColLtrs(iResultsCol) &amp;amp; ActiveCell.Row
        Result = ConvertUom(Range(strOrigValueCell))
      End If
    Next i
  End If
End With
' ... BAD EXAMPLE: DO NOT USE ...
&lt;/pre&gt;
      &lt;h4&gt;
        Example of Better Code&lt;/h4&gt;
      &lt;pre class="vb" name="code"&gt;' ...
Dim mySheet As Worksheet
Dim Value As Variant

Set mySheet = ActiveSheet

For i = iRow To iLastRow - 1
  Value = mySheet.Cells(i, iOutCol).Value
  If Value &amp;lt;&amp;gt; "" Then
    Result = ConvertUom(UnitSystem, Value)
  End If
Next i

' To get a column letter/code, do not reinvent the wheel!
' Various functions from:
' http://www.dicks-blog.com/archives/2004/05/21/column-numbers-to-letters/

Function ColLetter(ColNumber As Long) As String
    On Error Resume Next
    ColLetter = Application.Substitute(Application.ConvertFormula("R1C" &amp;amp; ColNumber, xlR1C1, xlA1, 4), "1", "")
End Function

Function ColumnLetter(ByVal c As Long) As String
  Dim p As Long
  While c
    p = 1 + (c - 1) Mod 26
    c = (c - p) \ 26
    ColumnLetter = Chr$(64 + p) &amp;amp; ColumnLetter
  Wend
End Function
&lt;/pre&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;h3&gt;
        Avoid using .Select and moving selection in macros unless absolutely.&lt;/h3&gt;
      Do not change the current sheet or selection unless that is the intention of the macro.
      In general, don't mess with the user, flip sheets, or other heinous acts and 
      try to leave things the way you found them.
      &lt;h4&gt;
        Example of Bad Code&lt;/h4&gt;
      &lt;pre class="vb" style="background-color: #ffdab9" name="code"&gt;' ... BAD EXAMPLE: DO NOT USE ...
For i = 1 To 10
  Range("A" &amp;amp; i).Select
  ActiveCell.Value = "Row " &amp;amp; i
Next i
' ... BAD EXAMPLE: DO NOT USE ...
&lt;/pre&gt;
      &lt;h4&gt;
        Example of Better Code&lt;/h4&gt;
      &lt;pre class="vb" name="code"&gt;Dim iColumn As Long
Dim mySheet As Worksheet
Dim myRange As Range

iColumn = 1
Set mySheet = ActiveSheet

For iRow = 1 To 10
  Set rng = mySheet.Cells(iRow, iColumn)
  rng.Value = "Row " &amp;amp; iRow
Next iRow
&lt;/pre&gt;
    &lt;/li&gt;
  &lt;/ol&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/68.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=7nVl_Kx0oX4:UKXiMcsUQGE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=7nVl_Kx0oX4:UKXiMcsUQGE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=7nVl_Kx0oX4:UKXiMcsUQGE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=7nVl_Kx0oX4:UKXiMcsUQGE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=7nVl_Kx0oX4:UKXiMcsUQGE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/05/27/macro-guidelines-for-excel-vba-beginners.aspx</guid>
            <pubDate>Tue, 27 May 2008 23:28:20 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/68.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/05/27/macro-guidelines-for-excel-vba-beginners.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/68.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/68.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/05/27/macro-guidelines-for-excel-vba-beginners.aspx</feedburner:origLink></item>
        <item>
            <title>When aspnet_regsql.exe won't connect</title>
            <category>ASP.NET</category>
            <category>SQL</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/oS5YV_8el9M/when-aspnet_regsql.exe-wont-connect.aspx</link>
            <description>&lt;p&gt;I was building a quick test web site and I was using the aspnet_regsql tool to add membership to a SQLEXPRESS database. At first, I tried:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;aspnet_regsql -A all -C "Data Source=.\SQLEXPRESS;Integrated Security=True;User Instance=True" -d "C:\code\Test\APP_DATA\aspnetdb.mdf"&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;For some reason, the SqlConnection insisted that it try to create the database and disregarded the full path to the database (note the path in the exception).&lt;/p&gt;&lt;pre&gt;SQL Exception:
System.Data.SqlClient.SqlException: Directory lookup for the file "C:\Documents and Settings\user\Local Settings\Application Data\Microsoft\Microsoft SQL Server Data\SQLEXPRESS\C:\code\Asp.net\ServerControlTest\App_Data\Database.mdf" failed with the operating system error 123(The filename, directory name, or volume label syntax is incorrect.).
CREATE DATABASE failed. Some file names listed could not be created. Check related errors.
Creating the C:\code\Asp.net\ServerControlTest\App_Data\Database database...
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at System.Web.Management.SqlServices.ExecuteFile(String file, String server, String database, String dbFileName, SqlConnection connection, Boolean sessionState, Boolean isInstall, SessionStateType sessionStatetype)
&lt;/pre&gt;
&lt;p&gt;Next I tried the simple commands (credit &lt;a href="http://www.4guysfromrolla.com/" target="_blank"&gt;Scott Mitchell&lt;/a&gt;) that worked great:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sqlcmd -S localhost\SQLExpress -Q "EXEC sp_attach_db 'Foobar', N'pathToDBfile'"&lt;br /&gt;aspnet_regsql.exe -S localhost\SQLExpress -d Foobar -E -A all&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;References&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://scottonwriting.net/sowblog/posts/5480.aspx" target="_blank"&gt;Working with SQL Server 2005 Express Database&lt;/a&gt; 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://weblogs.asp.net/lhunt/archive/2005/09/26/425966.aspx" target="_blank"&gt;Using ASPNET_RegSQL.exe with SQL Express databases in APP_DATA&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/67.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=oS5YV_8el9M:0EmmPEk1TTo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=oS5YV_8el9M:0EmmPEk1TTo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=oS5YV_8el9M:0EmmPEk1TTo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=oS5YV_8el9M:0EmmPEk1TTo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=oS5YV_8el9M:0EmmPEk1TTo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/04/24/when-aspnet_regsql.exe-wont-connect.aspx</guid>
            <pubDate>Thu, 24 Apr 2008 20:50:31 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/67.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/04/24/when-aspnet_regsql.exe-wont-connect.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/67.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/67.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/04/24/when-aspnet_regsql.exe-wont-connect.aspx</feedburner:origLink></item>
        <item>
            <title>Unable to log into SQL Server after creating self-signed SSL certificate</title>
            <category>SharePoint</category>
            <category>SQL</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/p3URq5DwxJA/unable-to-log-into-sql-server-after-creating-self-signed-ssl.aspx</link>
            <description>&lt;p&gt;In my &lt;a href="http://www.nimblecoder.com/blog/archive/2008/04/23/sharepoint-fba-limitations-and-options.aspx" target="_blank"&gt;SharePoint experiments&lt;/a&gt; with form-based authentication (FBA), I have been &lt;a title="Setting up SSL with a SelfSSL certificate" href="http://www.visualwin.com/SelfSSL/" target="_blank"&gt;installing self-signed SSL&lt;/a&gt; certificates since I am developing in a virtual machine without a certificate authority. Last night, I shut down my virtual machine instead of the usual Suspend operation. This morning, I started the virtual machine but SharePoint wasn't working and said: Cannot connect to the configuration database.&lt;/p&gt; &lt;p&gt;I then tried to open SQL Server Management Console and tried to connect, only to receive the following message:&lt;/p&gt; &lt;p&gt;&lt;a href="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/UnabletologintoSQLServeraftercreatingsel_A21D/SQL-Error-233-SSL.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="187" alt="A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.) (Microsoft SQL Server, Error: 233)" src="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/UnabletologintoSQLServeraftercreatingsel_A21D/SQL-Error-233-SSL_thumb.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;I didn't freak out, but I did check the SQL Server Service which was running, and then the SQL Server Log files which looked normal. There was one line which I didn't recognize:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;The certificate was successfully loaded for encryption.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This is actually a normal line in the log file, but it was then that I realized that the self-signed certificates I created were interfering with the login process. I searched around for Internet resources, but finally found what I was looking for in the &lt;a href="http://msdn2.microsoft.com/en-us/library/ms186362.aspx" target="_blank"&gt;Certificate MMC snap-in configuration&lt;/a&gt;. Since I had created multiple SSL certificates, I deleted the unused certificates and checked the encryption and certificate settings in the SQL Server Configuration Manager. After a quick reboot, I was back in business.&lt;/p&gt; &lt;p&gt;References:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms186362.aspx" target="_blank"&gt;Configuring Certificate for User by SSL&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://support.microsoft.com/kb/316898" target="_blank"&gt;How to enable SSL encryption for an instance of SQL Server&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://blogs.msdn.com/sql_protocols/archive/2005/12/22/506607.aspx" target="_blank"&gt;SQL Protocols: Troubleshoot Connectivity Issues in SQL Server 2005, Part III&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/66.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=p3URq5DwxJA:kDzzRVB17PU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=p3URq5DwxJA:kDzzRVB17PU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=p3URq5DwxJA:kDzzRVB17PU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=p3URq5DwxJA:kDzzRVB17PU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=p3URq5DwxJA:kDzzRVB17PU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/04/24/unable-to-log-into-sql-server-after-creating-self-signed-ssl.aspx</guid>
            <pubDate>Thu, 24 Apr 2008 16:29:18 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/66.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/04/24/unable-to-log-into-sql-server-after-creating-self-signed-ssl.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/66.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/66.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/04/24/unable-to-log-into-sql-server-after-creating-self-signed-ssl.aspx</feedburner:origLink></item>
        <item>
            <title>SharePoint FBA Limitations and Options</title>
            <category>ASP.NET</category>
            <category>SharePoint</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/SlzY1ZVtjRU/sharepoint-fba-limitations-and-options.aspx</link>
            <description>&lt;p&gt;I recently set up an isolated, single-server SharePoint site with forms-based authentication (FBA) with the hopes that it would eliminate the need to create unrelated user accounts for all of the SharePoint users. The FBA setup and installation went fine and I used the &lt;a href="http://www.codeplex.com/fba" target="_blank"&gt;SharePoint FBA tool&lt;/a&gt; on &lt;a href="http://www.codeplex.com/" target="_blank"&gt;codeplex&lt;/a&gt; to administer the accounts and users which is great.&lt;/p&gt; &lt;p&gt;Unfortunately I didn't realize that disabling "Client Integration" in the SharePoint Cental Admin / Application Management / Authentication Providers would have such a dramatic effect on usability. Some of the challenges are using SharePoint Designer, the MySites functionality is impacted, inability to export list data to Excel, as well as inability to integrate with Outlook. The composite screen shot below shows the difference between enabled and disabled client integration.&lt;/p&gt; &lt;p&gt;&lt;a href="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/SharePointFBALimitationsandOptions_8EF4/SharePoint%20Client%20Integration_2.png"&gt;&lt;img height="480" alt="SharePoint Client Integration" src="http://nimblecoder.com/blog/images/nimblecoder_com/blog/WindowsLiveWriter/SharePointFBALimitationsandOptions_8EF4/SharePoint%20Client%20Integration_thumb.png" width="569" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;After spending quite a bit of time configuring and setting up FBA, I don't want to abandon it immediately. I am looking into two options to use the FBA user store (ASPNETDB) with IIS, basic authentication, and SSL. The two likely candidates are &lt;a title="Supporting HTTP Authentication and Forms Authentication in a Single ASP.NET Web Site" href="http://msdn2.microsoft.com/en-us/library/aa479391.aspx" target="_blank"&gt;MADAM&lt;/a&gt; (Mixed Authentication Disposition ASP.NET Module) and &lt;a title="Custom Basic Authentication for IIS" href="http://www.codeplex.com/CustomBasicAuth" target="_blank"&gt;Custom Basic Authentication&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;I will post updates as available.&lt;/p&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/65.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=SlzY1ZVtjRU:8KClPrZDMe0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=SlzY1ZVtjRU:8KClPrZDMe0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=SlzY1ZVtjRU:8KClPrZDMe0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=SlzY1ZVtjRU:8KClPrZDMe0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=SlzY1ZVtjRU:8KClPrZDMe0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/04/23/sharepoint-fba-limitations-and-options.aspx</guid>
            <pubDate>Wed, 23 Apr 2008 15:07:22 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/65.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/04/23/sharepoint-fba-limitations-and-options.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/65.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/65.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/04/23/sharepoint-fba-limitations-and-options.aspx</feedburner:origLink></item>
        <item>
            <title>Just the facts, ma'am</title>
            <category>General</category>
            <category>JavaScript</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/sfGQ3-aftHQ/just-the-facts-maam.aspx</link>
            <description>&lt;p&gt;I was looking at &lt;a href="http://www.crockford.com/" target="_blank"&gt;Douglas Crockford's&lt;/a&gt; &lt;a href="http://blog.360.yahoo.com/douglascrockford" target="_blank"&gt;360 blog&lt;/a&gt; today and came across a &lt;a href="http://blog.360.yahoo.com/blog-TBPekxc1dLNy5DOloPfzVvFIVOWMB0li?p=814" target="_blank"&gt;hilarious quote&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Do you write regularly for any publications in this field? &lt;/em&gt; &lt;/p&gt;&lt;p&gt;Just the blogs.  &lt;/p&gt;&lt;p&gt;&lt;em&gt;In researching the book, did you come across any surprising facts, figures, or statistics that the press might be interested in?&lt;/em&gt;  &lt;/p&gt;&lt;p&gt;&lt;span style="background-color: #e0e0e0"&gt;Surprisingly, facts have very little to do with web development.&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Douglas Crockford is simply amazing and is the original author of &lt;a title="expat XML parser" href="http://expat.sourceforge.net/" target="_blank"&gt;expat&lt;/a&gt; (one of the first XML parsing libraries), as well as &lt;a title="JavaScript verifier" href="http://www.jslint.com/" target="_blank"&gt;JSLint&lt;/a&gt;, &lt;a title="JavaScript Minifier" href="http://javascript.crockford.com/jsmin.html" target="_blank"&gt;JSMin&lt;/a&gt;, and &lt;a title="JavaScript Object Notation" href="http://www.json.org/" target="_blank"&gt;JSON&lt;/a&gt; (one of the primary components of AJAX).&lt;/p&gt; &lt;p&gt;P.S. Bonus points for any one identifying the blog post title source.&lt;/p&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/64.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=sfGQ3-aftHQ:JXKOKZOZZOQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=sfGQ3-aftHQ:JXKOKZOZZOQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=sfGQ3-aftHQ:JXKOKZOZZOQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=sfGQ3-aftHQ:JXKOKZOZZOQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=sfGQ3-aftHQ:JXKOKZOZZOQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/04/21/just-the-facts-maam.aspx</guid>
            <pubDate>Mon, 21 Apr 2008 15:15:15 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/64.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/04/21/just-the-facts-maam.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/64.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/64.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/04/21/just-the-facts-maam.aspx</feedburner:origLink></item>
        <item>
            <title>SharePoint FBA Configuration and machine.config</title>
            <category>SharePoint</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/XLaWtbGTfV4/sharepoint-fba-configuration-and-machine.config.aspx</link>
            <description>&lt;p&gt;I recently implemented Forms-Based Authentication (FBA) in MOSS 2007 and had it working great. Unfortunately we had to reinstall the system and I actually had more issues getting FBA to work correctly on the reinstall than I did the first time. It turned out that the issue was mixing different implementation methods that counteracted each other. The simplest way to configure FBA is to edit the machine.config file on the server (%WINDOWS%\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config) and change the LocalSqlServer connection string to the ASPNETDB user store or other database with the user information. This takes advantage of the pre-configured AspNetSqlMembershipProvider and AspNetSqlRoleProvider in the &amp;lt;system.web&amp;gt;&amp;lt;membership&amp;gt; and &amp;lt;roleManager&amp;gt; sections. The AspNetSqlMembershipProvider and AspNetSqlRoleProvider sections normally include something similar to:&lt;/p&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;system.web&amp;gt;
  &amp;lt;membership&amp;gt;
    &amp;lt;providers&amp;gt;
      &amp;lt;add
        name="AspNetSqlMembershipProvider"
        type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        connectionStringName="LocalSqlServer"
        enablePasswordRetrieval="false"
        enablePasswordReset="true"
        requiresQuestionAndAnswer="true"
        applicationName="/"
        requiresUniqueEmail="false"
        passwordFormat="Hashed"
        maxInvalidPasswordAttempts="5"
        minRequiredPasswordLength="7"
        minRequiredNonalphanumericCharacters="1"
        passwordAttemptWindow="10"
        passwordStrengthRegularExpression=""
      /&amp;gt;
    &amp;lt;/providers&amp;gt;
  &amp;lt;/membership&amp;gt;
  &amp;lt;roleManager&amp;gt;
    &amp;lt;providers&amp;gt;
      &amp;lt;add
        name="AspNetSqlRoleProvider"
        connectionStringName="LocalSqlServer"
        applicationName="/" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
      /&amp;gt;
      &amp;lt;add
        name="AspNetWindowsTokenRoleProvider"
        applicationName="/"
        type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
      /&amp;gt;
    &amp;lt;/providers&amp;gt;
  &amp;lt;/roleManager&amp;gt;
&amp;lt;/system.web&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The important thing to note is the connectionStringName attributes that are configured to use LocalSqlServer. If you change the settings for LocalSqlServer then the membership and roleManager will automatically use the updated setting.&lt;/p&gt;
&lt;p&gt;Many SharePoint FBA guides recommend changing the web.config for the web application. This is still a good recommendation however if you choose this implementation method, be sure not to use both methods and edit both the machine.config and web.config. For example, I added the following to my web.config:&lt;/p&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;system.web&amp;gt;
  &amp;lt;!-- This caused the SharePoint authentication to fail.
       I already knew these providers were configured in the machine.config,
       so I simply referenced them. --&amp;gt;
  &amp;lt;membership defaultProvider="AspNetSqlMembershipProvider" /&amp;gt;
  &amp;lt;roleManager defaultProvider="AspNetSqlRoleProvider" enabled="true" /&amp;gt;
&lt;/pre&gt;
&lt;p&gt;What happened is that I tried to login and I would see an "Access Denied" screen. I double-checked the Site collection administrators in the SharePoint Central Administration and it was set properly but I was unable to access any content using FBA. Eventually it dawned on me to remove the configuration from the web.config and simply try the settings in Central Administration under Application Management \ Authentication providers. Once I removed the redundant information in web.config, FBA worked again.&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:5f1f6b19-c0ca-4ce8-9788-e61971de936c" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/SharePoint" rel="tag"&gt;SharePoint&lt;/a&gt;, &lt;a href="http://technorati.com/tags/MOSS%202007" rel="tag"&gt;MOSS 2007&lt;/a&gt;, &lt;a href="http://technorati.com/tags/FBA" rel="tag"&gt;FBA&lt;/a&gt;&lt;/div&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/63.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=XLaWtbGTfV4:RPRzSZpP8QU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=XLaWtbGTfV4:RPRzSZpP8QU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=XLaWtbGTfV4:RPRzSZpP8QU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=XLaWtbGTfV4:RPRzSZpP8QU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=XLaWtbGTfV4:RPRzSZpP8QU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/04/14/sharepoint-fba-configuration-and-machine.config.aspx</guid>
            <pubDate>Mon, 14 Apr 2008 20:23:10 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/63.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/04/14/sharepoint-fba-configuration-and-machine.config.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/63.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/63.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/04/14/sharepoint-fba-configuration-and-machine.config.aspx</feedburner:origLink></item>
        <item>
            <title>Overcoming SQL GROUP BY challenges with ROW_NUMBER</title>
            <category>SQL</category>
            <link>http://feedproxy.google.com/~r/NimbleCoder/~3/afx0WlbQueE/overcoming-sql-group-by-challenges-with-row_number.aspx</link>
            <description>&lt;p&gt;In SQL, aggregate functions will return the group by values or the aggregate function results, but it is difficult (or at least harder than it should be) to return the primary key or ROWID. In contrast, most programming languages will return the instance (or a pointer/reference to the instance) when searching for items.&lt;/p&gt; &lt;h4&gt;Background&lt;/h4&gt; &lt;p&gt;A project manager allocated me several weeks ago on emergency basis to help out with another project that was having difficulties with a SQL Historian system. I ended up developing a nice set of SQL tables, functions, and stored procedures to transfer data from a remote linked server into the Historian. It was actually rather fun to work on as it had several challenging aspects. Of course, after several late nights of development, I don't know how much fun like that I could take!&lt;/p&gt; &lt;p&gt;The key to the data transfer was obtaining the latest data from the remote database and inserting it into the Historian. The remote database was an Oracle database and the Historian was a SQL Server database. My first reaction was to do a simple query with a TOP specification but Oracle doesn't have a TOP function so I started to search for ways to achieve the same result. I came across the &lt;a href="http://msdn2.microsoft.com/en-us/library/ms186734.aspx" target="_blank"&gt;ROW_NUMBER()&lt;/a&gt; function and it did the trick although it required a sub-query such as:&lt;/p&gt;&lt;pre class="sql" name="code"&gt;SELECT  *
FROM    (
    SELECT
        SAMPLE_DAY
    ,   ASSET
    ,   TANK_LEVEL_MM
    ,   TANK_PRES_PSIG
    ,   TANK_VOL_M3
    ,   FEED_FLOW_M3HR
    ,   ROW_NUMBER() OVER (PARTITION BY ASSET ORDER BY SAMPLE_DAY DESC) RN
    FROM    REMOTE_DATA_VIEW_1
    ORDER BY ASSET, SAMPLE_DAY DESC
)
WHERE   RN = 1
&lt;/pre&gt;
&lt;p&gt;It turns out that this query is more powerful than the TOP query as it essentially performs a GROUP BY aggregate (ASSET and order by SAMPLE_DAY descending) without some of the limitations of SQL aggregate functions.&lt;/p&gt;
&lt;h4&gt;Exploring Aggregate Queries&lt;/h4&gt;
&lt;p&gt;In a traditional SQL aggregate query, the columns returned by the query have to be in the GROUP BY clause or in an aggregate function. This means that it is difficult to return the primary key for a table because you usually are grouping by a name, location, or other non-unique field. Here is an example:&lt;/p&gt;&lt;pre class="sql" name="code"&gt;-- DDL: This table stores the tag names, source, and values. This
-- table is just for demonstrative purposes and does not represent
-- a normalized structure.
CREATE TABLE TAG_VALUE
(
    ValueID             int             IDENTITY    PRIMARY KEY
,   DateTime            datetime        NOT NULL
,   TagName             varchar(50)     NOT NULL
,   Value               numeric             NULL
,   Ignored             bit             NOT NULL    DEFAULT 0
,   Processed           bit             NOT NULL    DEFAULT 0
)
GO

-- Get the most recent entry grouped by tag name
SELECT  TagName
,       MAX(DateTime) AS DateTime
FROM    TAG_VALUE
GROUP BY TagName
&lt;/pre&gt;
&lt;p&gt;If you try to put the primary key as a return column, you will get an error. Unfortunately this means you end up having an ugly subquery and potentially expensive (hopefully you have indices on the matching columns as well), such as:&lt;/p&gt;&lt;pre class="sql" name="code"&gt;SELECT  ValueID
FROM    TAG_VALUE   AS V1
    JOIN (

        SELECT  TagName
        ,       MAX(DateTime) AS DateTime
        FROM    TAG_VALUE
        GROUP BY TagName

    )               AS V2
    ON (    (V1.TagName  = V2.TagName)
        AND (V1.DateTime = V2.DateTime))
&lt;/pre&gt;
&lt;h4&gt;Using ROW_NUMBER&lt;/h4&gt;
&lt;p&gt;The ROW_NUMBER function has the powerful feature of specifying the PARTITION BY which provides some of the same functionality that GROUP BY would perform but with less hassle. For example, the following query analyzes the TAG_VALUE table and looks for duplicate TagName rows. It then marks the "old" values as "Ignored" and leaves the newest entry alone.&lt;/p&gt;&lt;pre class="sql" name="code"&gt;UPDATE  TAG_VALUE
SET     Ignored = 1
FROM    TAG_VALUE AS V1
    JOIN (
        SELECT  ValueID
        ,       ROW_NUMBER() OVER (PARTITION BY TagName ORDER BY DateTime DESC) AS RN
        FROM    TAG_VALUE
        WHERE   TagName IN (
            SELECT DISTINCT TagName
            FROM        TAG_VALUE
            GROUP BY    TagName
            HAVING      COUNT(TagName) &amp;gt; 1
            )
    ) AS V2
    ON (V1.ValueID = V2.ValueID)
WHERE   RN &amp;gt; 1
&lt;/pre&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;So, in conclusion, ROW_NUMBER provides an easier method of returning the actual row so you can perform updates, deletes, or return the primary key.&lt;/p&gt;
&lt;hr /&gt;

&lt;h4&gt;Sample SQL Code&lt;/h4&gt;&lt;pre class="sql" name="code"&gt;/* ====
NOTE: The table structure resembles a database design that I have seen used.
I did not design the table structure and it is intentionally flat. Originally
this example used a remote query to allow SQL Server to query ORACLE, but for
the sample it is all in SQL Server. With very minor changes it works in Oracle
as well.
==== */

-- DDL: This table simulates a remote linked server
CREATE TABLE REMOTE_DATA_VIEW_1
(
    SAMPLE_DAY          datetime
,   ASSET               varchar(50)
,   TANK_LEVEL_MM       numeric
,   TANK_PRES_PSIG      numeric
,   TANK_VOL_M3         numeric
,   FEED_FLOW_M3HR      numeric
)
GO

-- Sample data
INSERT REMOTE_DATA_VIEW_1 VALUES ('2008-02-04', 'ASSET_01', 1200.0, 18.5, 100.0, 150.0)
INSERT REMOTE_DATA_VIEW_1 VALUES ('2008-02-01', 'ASSET_01', 1100.0, 17.5,  90.0, 145.0)
INSERT REMOTE_DATA_VIEW_1 VALUES ('2008-01-25', 'ASSET_01', 1000.0, 16.5,  80.0, 155.0)
INSERT REMOTE_DATA_VIEW_1 VALUES ('2008-02-03', 'ASSET_02',  800.0, 19.5, 110.0, 160.0)
INSERT REMOTE_DATA_VIEW_1 VALUES ('2008-02-02', 'ASSET_02',  750.0, 17.0,  95.0, 165.0)
INSERT REMOTE_DATA_VIEW_1 VALUES ('2008-02-04', 'ASSET_03', 1500.0, 18.0, 100.0, 170.0)
INSERT REMOTE_DATA_VIEW_1 VALUES ('2008-01-31', 'ASSET_04', 1350.0, 19.0,  90.0, 135.0)
GO


-- Return the raw data
SELECT
    SAMPLE_DAY
,   ASSET
,   TANK_LEVEL_MM
,   TANK_PRES_PSIG
,   TANK_VOL_M3
,   FEED_FLOW_M3HR
,   ROW_NUMBER() OVER (PARTITION BY ASSET ORDER BY SAMPLE_DAY DESC) RN
FROM    REMOTE_DATA_VIEW_1
ORDER BY ASSET, SAMPLE_DAY DESC

/* ====
SAMPLE_DAY              ASSET    TANK_LEVEL_MM TANK_PRES_PSIG TANK_VOL_M3 FEED_FLOW_M3HR RN
----------------------- -------- ------------- -------------- ----------- -------------- --
2008-02-04 00:00:00.000 ASSET_01 1200          19             100         150            1
2008-02-01 00:00:00.000 ASSET_01 1100          18             90          145            2
2008-01-25 00:00:00.000 ASSET_01 1000          17             80          155            3
2008-02-03 00:00:00.000 ASSET_02 800           20             110         160            1
2008-02-02 00:00:00.000 ASSET_02 750           17             95          165            2
2008-02-04 00:00:00.000 ASSET_03 1500          18             100         170            1
2008-01-31 00:00:00.000 ASSET_04 1350          19             90          135            1
==== */


-- Use a simple embedded query
SELECT  *
FROM    (
    SELECT
        SAMPLE_DAY
    ,   ASSET
    ,   TANK_LEVEL_MM
    ,   TANK_PRES_PSIG
    ,   TANK_VOL_M3
    ,   FEED_FLOW_M3HR
    ,   ROW_NUMBER() OVER (PARTITION BY ASSET ORDER BY SAMPLE_DAY DESC) AS RN
    FROM
        REMOTE_DATA_VIEW_1
    )   DATA
WHERE   RN = 1

/* ====
SAMPLE_DAY              ASSET    TANK_LEVEL_MM TANK_PRES_PSIG TANK_VOL_M3 FEED_FLOW_M3HR RN
----------------------- -------- ------------- -------------- ----------- -------------- --
2008-02-04 00:00:00.000 ASSET_01 1200          19             100         150            1
2008-02-03 00:00:00.000 ASSET_02 800           20             110         160            1
2008-02-04 00:00:00.000 ASSET_03 1500          18             100         170            1
2008-01-31 00:00:00.000 ASSET_04 1350          19             90          135            1
==== */


-- This is an uglier version of the query above but provided for comparison.
-- Return only the most recent entry using SAMPLE_DAY and ASSET as keys. On a production
-- table, there should be a real primary key or ROWID that you would use instead.
SELECT
    DATA.SAMPLE_DAY
,   DATA.ASSET
,   DATA.TANK_LEVEL_MM
,   DATA.TANK_PRES_PSIG
,   DATA.TANK_VOL_M3
,   DATA.FEED_FLOW_M3HR
FROM    (

        SELECT
            SAMPLE_DAY
        ,   ASSET
        ,   ROW_NUMBER() OVER (PARTITION BY ASSET ORDER BY SAMPLE_DAY DESC) AS RN
        FROM
            REMOTE_DATA_VIEW_1

    )   AS  REMOTE_QUERY
    JOIN    REMOTE_DATA_VIEW_1  AS DATA
        ON (    (REMOTE_QUERY.SAMPLE_DAY  = DATA.SAMPLE_DAY)
            AND (REMOTE_QUERY.ASSET       = DATA.ASSET) )

WHERE   REMOTE_QUERY.RN = 1
ORDER BY DATA.ASSET, DATA.SAMPLE_DAY DESC

/* ====
SAMPLE_DAY              ASSET    TANK_LEVEL_MM TANK_PRES_PSIG TANK_VOL_M3 FEED_FLOW_M3HR
----------------------- -------- ------------- -------------- ----------- --------------
2008-02-04 00:00:00.000 ASSET_01 1200          19             100         150
2008-02-03 00:00:00.000 ASSET_02 800           20             110         160
2008-02-04 00:00:00.000 ASSET_03 1500          18             100         170
2008-01-31 00:00:00.000 ASSET_04 1350          19             90          135
==== */
GO

&lt;/pre&gt;
&lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2d6788fa-f0bb-4042-a2bc-6172a8115516" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/SQL" rel="tag"&gt;SQL&lt;/a&gt;, &lt;a href="http://technorati.com/tags/SQL%20Server" rel="tag"&gt;SQL Server&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Oracle" rel="tag"&gt;Oracle&lt;/a&gt;&lt;/div&gt;&lt;img src="http://nimblecoder.com/blog/aggbug/62.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=afx0WlbQueE:Y5PJBVW64C4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=afx0WlbQueE:Y5PJBVW64C4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=afx0WlbQueE:Y5PJBVW64C4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/NimbleCoder?a=afx0WlbQueE:Y5PJBVW64C4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/NimbleCoder?i=afx0WlbQueE:Y5PJBVW64C4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Ryan Van Slooten</dc:creator>
            <guid isPermaLink="false">http://nimblecoder.com/blog/archive/2008/04/14/overcoming-sql-group-by-challenges-with-row_number.aspx</guid>
            <pubDate>Mon, 14 Apr 2008 19:35:46 GMT</pubDate>
            <wfw:comment>http://nimblecoder.com/blog/comments/62.aspx</wfw:comment>
            <comments>http://nimblecoder.com/blog/archive/2008/04/14/overcoming-sql-group-by-challenges-with-row_number.aspx#feedback</comments>
            <wfw:commentRss>http://nimblecoder.com/blog/comments/commentRss/62.aspx</wfw:commentRss>
            <trackback:ping>http://nimblecoder.com/blog/services/trackbacks/62.aspx</trackback:ping>
        <feedburner:origLink>http://nimblecoder.com/blog/archive/2008/04/14/overcoming-sql-group-by-challenges-with-row_number.aspx</feedburner:origLink></item>
    </channel>
</rss>
