<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Paul Mrozowski's Blog</title>
    <link>http://www.rcs-solutions.com/blog/</link>
    <description>A day in the life (of a developer)</description>
    <language>en-us</language>
    <copyright>Paul Mrozowski / RCS Solutions, Inc.</copyright>
    <lastBuildDate>Wed, 24 Nov 2010 01:54:04 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>paulm@rcs-solutions.com</managingEditor>
    <webMaster>paulm@rcs-solutions.com</webMaster>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=c3498c80-09ad-42a8-a4e0-6e7f03caceb0</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,c3498c80-09ad-42a8-a4e0-6e7f03caceb0.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,c3498c80-09ad-42a8-a4e0-6e7f03caceb0.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=c3498c80-09ad-42a8-a4e0-6e7f03caceb0</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A few years ago I needed the ability to “autolink” text – basically, I had a list
of keywords and anytime those keywords were displayed on a page I needed to have them
turned into a link. The code is relatively straightforward, but I thought it might
be of some use to other people.
</p>
        <pre style="background-color: #f7f7f7; font-family: ">
          <font face="Consolas">
            <span>
              <font color="#0000ff">
                <font style="font-size: 12pt">using</font>
              </font>
            </span>
            <font style="font-size: 12pt"> System;<br /><span><font color="#0000ff">using</font></span> System.Collections.Generic;<br /><span><font color="#0000ff">using</font></span> System.Linq;<br /><span><font color="#0000ff">using</font></span> System.Text;<br /><span><font color="#0000ff">using</font></span> System.Text.RegularExpressions;<br /><br /><span><font color="#0000ff">namespace</font></span> RCSSolutions<br />
{<br />
    <span><font color="#0000ff">public</font></span> <span><font color="#0000ff">class</font></span> <span><font color="#2b91af">Term</font></span><br />
    {<br />
        <span><font color="#0000ff">public</font></span> <span><font color="#0000ff">string</font></span> LinkTerm
{ <span><font color="#0000ff">get</font></span>; <span><font color="#0000ff">set</font></span>;
}        
<br />
        <span><font color="#0000ff">public</font></span> <span><font color="#0000ff">string</font></span> Url
{ <span><font color="#0000ff">get</font></span>; <span><font color="#0000ff">set</font></span>;
}<br />
        <span><font color="#0000ff">public</font></span> <span><font color="#0000ff">string</font></span> Target
{ <span><font color="#0000ff">get</font></span>; <span><font color="#0000ff">set</font></span>;
}<br />
    }<br /><br />
    <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;summary&gt;</font></span><br />
    <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> Adds
links to a passed in string based on records in</font></span><br />
    <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> the
SourceAutolink table.</font></span><br />
    <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;/summary&gt;</font></span><br />
    <span><font color="#0000ff">public</font></span> <span><font color="#0000ff">class</font></span> <span><font color="#2b91af">AutoLinker</font></span><br />
    {             
<br />
        <span><font color="#0000ff">private</font></span> <span><font color="#0000ff">string</font></span> m_linkStyle
= <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #e5e5e5">""</font></span>;<br /><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;summary&gt;</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">List
of words which auto link</font></span><span><font color="#808080">&lt;/summary&gt;</font></span><br />
        <span><font color="#0000ff">public</font></span> <span><font color="#2b91af">List</font></span>&lt;<span><font color="#2b91af">Term</font></span>&gt;
LinkWords { <span><font color="#0000ff">get</font></span>; <span><font color="#0000ff">set</font></span>;
}<br /><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;summary&gt;</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">The
CSS class to assign to the link tag</font></span><span><font color="#808080">&lt;/summary&gt;</font></span><br />
        <span><font color="#0000ff">public</font></span> <span><font color="#0000ff">string</font></span> LinkStyle<br />
        {<br />
            <span><font color="#0000ff">get</font></span> { <span><font color="#0000ff">return</font></span> <span><font color="#0000ff">this</font></span>.m_linkStyle;
}<br />
            <span><font color="#0000ff">set</font></span> { <span><font color="#0000ff">this</font></span>.m_linkStyle
= <span><font color="#0000ff">value</font></span>; }<br />
        }<br /><br />
        <span><font color="#0000ff">public</font></span> AutoLinker
(<span><font color="#2b91af">List</font></span>&lt;<span><font color="#2b91af">Term</font></span>&gt;
linkWords)<br />
        {<br />
            LinkWords = linkWords;<br />
        }<br /><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;summary&gt;</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> Adds
any links to the passed in content.</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;/summary&gt;</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><font color="#808080"><span>&lt;param
name=</span><span>"content"</span><span>&gt;</span></font><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">Content
to evaluate</font></span><span><font color="#808080">&lt;/param&gt;</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;returns&gt;</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">Marked
up results</font></span><span><font color="#808080">&lt;/returns&gt;</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;developer&gt;</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">Paul
Mrozowski</font></span><span><font color="#808080">&lt;/developer&gt;</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;created&gt;</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">07/07/2008</font></span><span><font color="#808080">&lt;/created&gt;</font></span><br />
        <span><font color="#0000ff">public</font></span> <span><font color="#0000ff">string</font></span> AutoLink(<span><font color="#0000ff">string</font></span> content)<br />
        {<br />
            <span><font color="#0000ff">if</font></span> (<span><font color="#0000ff">this</font></span>.LinkWords
== <span><font color="#0000ff">null</font></span>)<br />
                <span><font color="#0000ff">return</font></span> content;<br />
            
<br />
            <span><font color="#2b91af">StringBuilder</font></span> result
= <span><font color="#0000ff">new</font></span> <span><font color="#2b91af">StringBuilder</font></span>();<br /><br />
            <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
Replaces HTML (and html-like) tags with spaces (we want to keep</font></span><br />
            <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
the same relative positions of everything else in the text since</font></span><br />
            <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
we're going to use them to do the final replacements.)</font></span><br />
            <span><font color="#0000ff">string</font></span> newSentence
= <span><font color="#2b91af">Regex</font></span>.Replace(content,<br />
                                     <span><font color="#a31515">@"&lt;(.|\n)*?&gt;"</font></span>,<br />
                                    
match =&gt; <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #e5e5e5">"
"</font></span>.PadRight(match.Length));<br /><br />
            <span><font color="#0000ff">string</font></span> tmpContent
= content;<br /><br />
            <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
Loop through each link term, search for matches. Save each of them into a new collection</font></span><br />
            <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
We're going to use the results to sort the matches in decending order by location.
That</font></span><br />
            <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
way we can perform the replacements w/o moving the starting location of the other
replacements.</font></span><br />
            <span><font color="#0000ff">foreach</font></span> (<span><font color="#0000ff">var</font></span> linkRow <span><font color="#0000ff">in</font></span> LinkWords)<br />
            {<br />
                <span><font color="#0000ff">var</font></span> allMatches
= <span><font color="#0000ff">new</font></span> <span><font color="#2b91af">List</font></span>&lt;<span><font color="#2b91af">Match</font></span>&gt;();<br />
                <span><font color="#2b91af">MatchCollection</font></span> matches
= <span><font color="#2b91af">Regex</font></span>.Matches(newSentence, linkRow.LinkTerm, <span><font color="#2b91af">RegexOptions</font></span>.IgnoreCase);<br />
                <span><font color="#0000ff">foreach</font></span> (<span><font color="#2b91af">Match</font></span> match <span><font color="#0000ff">in</font></span> matches)<br />
                   
allMatches.Add(match);<br /><br />
                <span><font color="#0000ff">var</font></span> orderedMatches
= <span><font color="#0000ff">from</font></span> m <span><font color="#0000ff">in</font></span> allMatches<br />
                                     <span><font color="#0000ff">orderby</font></span> m.Index <span><font color="#0000ff">descending</font></span><br />
                                     <span><font color="#0000ff">select</font></span> m;<br /><br />
                <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
General idea is to grab all of the text following the match, get the newly</font></span><br />
                <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
link word w/html markup and insert it before the this text. Then truncate</font></span><br />
                <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
the original content to remove everything from the starting position of the</font></span><br />
                <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
match to the end of file - this is basically done so I don't have to track</font></span><br />
                <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
the current position within the file. After we're done with the loop we</font></span><br />
                <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
insert anything that's left to the beginning of the new string.</font></span><br />
                <span><font color="#0000ff">foreach</font></span> (<span><font color="#2b91af">Match</font></span> item <span><font color="#0000ff">in</font></span> orderedMatches)<br />
               
{<br />
                    <span><font color="#0000ff">string</font></span> endOfMatchedStringToEOF
= tmpContent.Substring(item.Index + item.Length);<br />
                   
result.Insert(0, GetAutolinkText(linkRow, item.Value) + endOfMatchedStringToEOF);<br />
                   
tmpContent = tmpContent.Substring(0, item.Index);<br />
               
}<br />
            }<br /><br />
            result.Insert(0,
tmpContent);<br /><br />
            <span><font color="#0000ff">return</font></span> result.ToString();<br />
        }<br /><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;summary&gt;</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> Get
the replacement text.</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;/summary&gt;</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><font color="#808080"><span>&lt;param
name=</span><span>"token"</span><span>&gt;</span></font><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">Word
token</font></span><span><font color="#808080">&lt;/param&gt;</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><font color="#808080"><span>&lt;param
name=</span><span>"content"</span><span>&gt;</span></font><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">Original
content</font></span><span><font color="#808080">&lt;/param&gt;</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;returns&gt;</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">Empty
string if no replacement</font></span><span><font color="#808080">&lt;/returns&gt;</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;developer&gt;</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">Paul
Mrozowski</font></span><span><font color="#808080">&lt;/developer&gt;</font></span><br />
        <span><font color="#808080">///</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf"> </font></span><span><font color="#808080">&lt;created&gt;</font></span><span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">07/08/2008</font></span><span><font color="#808080">&lt;/created&gt;</font></span><br />
        <span><font color="#0000ff">private</font></span> <span><font color="#0000ff">string</font></span> GetAutolinkText(<span><font color="#2b91af">Term</font></span> linkTo, <span><font color="#0000ff">string</font></span> match)<br />
        {<br />
            <span><font color="#0000ff">string</font></span> newWord
= match;<br /><br />
            <span><font color="#0000ff">if</font></span> (<span><font color="#0000ff">this</font></span>.m_linkStyle.Length
== 0)<br />
               
newWord = <span><font color="#0000ff">string</font></span>.Format(<span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #e5e5e5">"&lt;a
href='{0}' "</font></span>, linkTo.Url);<br />
            <span><font color="#0000ff">else</font></span><br />
               
newWord = <span><font color="#0000ff">string</font></span>.Format(<span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #e5e5e5">"&lt;a
class='{0}' href='{1}' "</font></span>, 
<br />
                                        <span><font color="#0000ff">this</font></span>.LinkStyle, 
<br />
                                       
linkTo.Url);<br /><br />
            <span><font color="#0000ff">if</font></span> ((linkTo.Target
?? <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #e5e5e5">""</font></span>).Length
&gt; 0)<br />
               
newWord += <span><font color="#0000ff">string</font></span>.Format(<span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #e5e5e5">"target='{0}'
"</font></span>, linkTo.Target);<br /><br />
            <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #ffffbf">//
We pass in the original match term to maintain its case (the initial match was case-insensitive).</font></span><br />
            newWord += <span><font color="#0000ff">string</font></span>.Format(<span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #e5e5e5">"&gt;{0}&lt;/a&gt;"</font></span>,
match);<br /><br />
            <span><font color="#0000ff">return</font></span> newWord;<br />
        }<br />
    }<br />
}</font>
          </font>
          <br />
        </pre>
        <p>
Usage is simple – create a list of terms that you want linked (along with the URL,
style (if any), and target) and pass it to the AutoLinker class, then call AutoLink
with your source text. It will return the text with the links embedded in it. Here’s
a sample from a console application:
</p>
        <pre>
          <font face="Consolas">
            <font style="font-size: 12pt">        <span><font color="#0000ff">static</font></span> <span><font color="#0000ff">void</font></span> Main(<span><font color="#0000ff">string</font></span>[]
args)<br />
        {<br />
            <span><font color="#0000ff">var</font></span> terms
= <span><font color="#0000ff">new</font></span> <span><font color="#2b91af">List</font></span>&lt;<span><font color="#2b91af">Term</font></span>&gt;();<br />
            terms.Add(<span><font color="#0000ff">new</font></span> <span><font color="#2b91af">Term</font></span>()
{ LinkTerm = <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #e5e5e5">"Hello"</font></span>,
Target = <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #e5e5e5">"_blank"</font></span>,
Url = <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #e5e5e5">"http://www.rcs-solutions.com"</font></span> });<br /><br />
            <span><font color="#0000ff">string</font></span> sentence
= <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"><font style="background-color: #e5e5e5">"Why,
hello! This is a sentence where I'm going to link to the word \"hello\"."</font></span>;<br />
            <span><font color="#2b91af">Console</font></span>.Write(sentence);<br />
            <span><font color="#0000ff">var</font></span> linker
= <span><font color="#0000ff">new</font></span> <span><font color="#2b91af">AutoLinker</font></span>(terms);<br />
            
<br />
            <span><font color="#2b91af">Console</font></span>.Write(linker.AutoLink(sentence));<br />
            <span><font color="#2b91af">Console</font></span>.ReadKey();<br />
        }</font>
          </font>
        </pre>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=c3498c80-09ad-42a8-a4e0-6e7f03caceb0" />
      </body>
      <title>Auto Linking Text in a Web Page</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,c3498c80-09ad-42a8-a4e0-6e7f03caceb0.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2010/11/24/AutoLinkingTextInAWebPage.aspx</link>
      <pubDate>Wed, 24 Nov 2010 01:54:04 GMT</pubDate>
      <description>&lt;p&gt;
A few years ago I needed the ability to “autolink” text – basically, I had a list
of keywords and anytime those keywords were displayed on a page I needed to have them
turned into a link. The code is relatively straightforward, but I thought it might
be of some use to other people.
&lt;/p&gt;
&lt;pre style="background-color: #f7f7f7; font-family: "&gt;&lt;font face="Consolas"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 12pt"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 12pt"&gt; System;&lt;br /&gt;
&lt;span&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;
&lt;span&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Linq;&lt;br /&gt;
&lt;span&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Text;&lt;br /&gt;
&lt;span&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Text.RegularExpressions;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;&lt;font color="#0000ff"&gt;namespace&lt;/font&gt;&lt;/span&gt; RCSSolutions&lt;br /&gt;
{&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#2b91af"&gt;Term&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; LinkTerm
{ &lt;span&gt;&lt;font color="#0000ff"&gt;get&lt;/font&gt;&lt;/span&gt;; &lt;span&gt;&lt;font color="#0000ff"&gt;set&lt;/font&gt;&lt;/span&gt;;
}&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; Url
{ &lt;span&gt;&lt;font color="#0000ff"&gt;get&lt;/font&gt;&lt;/span&gt;; &lt;span&gt;&lt;font color="#0000ff"&gt;set&lt;/font&gt;&lt;/span&gt;;
}&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; Target
{ &lt;span&gt;&lt;font color="#0000ff"&gt;get&lt;/font&gt;&lt;/span&gt;; &lt;span&gt;&lt;font color="#0000ff"&gt;set&lt;/font&gt;&lt;/span&gt;;
}&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;summary&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt; Adds
links to a passed in string based on records in&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt; the
SourceAutolink table.&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#2b91af"&gt;AutoLinker&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; {&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; m_linkStyle
= &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #e5e5e5"&gt;&amp;quot;&amp;quot;&lt;/font&gt;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;summary&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;List
of words which auto link&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;Term&lt;/font&gt;&lt;/span&gt;&amp;gt;
LinkWords { &lt;span&gt;&lt;font color="#0000ff"&gt;get&lt;/font&gt;&lt;/span&gt;; &lt;span&gt;&lt;font color="#0000ff"&gt;set&lt;/font&gt;&lt;/span&gt;;
}&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;summary&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;The
CSS class to assign to the link tag&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; LinkStyle&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;get&lt;/font&gt;&lt;/span&gt; { &lt;span&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.m_linkStyle;
}&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;set&lt;/font&gt;&lt;/span&gt; { &lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.m_linkStyle
= &lt;span&gt;&lt;font color="#0000ff"&gt;value&lt;/font&gt;&lt;/span&gt;; }&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; AutoLinker
(&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;Term&lt;/font&gt;&lt;/span&gt;&amp;gt;
linkWords)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LinkWords = linkWords;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;summary&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt; Adds
any links to the passed in content.&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;font color="#808080"&gt;&lt;span&gt;&amp;lt;param
name=&lt;/span&gt;&lt;span&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;Content
to evaluate&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;returns&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;Marked
up results&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/returns&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;developer&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;Paul
Mrozowski&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/developer&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;created&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;07/07/2008&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/created&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; AutoLink(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; content)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.LinkWords
== &lt;span&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt; content;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#2b91af"&gt;StringBuilder&lt;/font&gt;&lt;/span&gt; result
= &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#2b91af"&gt;StringBuilder&lt;/font&gt;&lt;/span&gt;();&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
Replaces HTML (and html-like) tags with spaces (we want to keep&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
the same relative positions of everything else in the text since&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
we're going to use them to do the final replacements.)&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; newSentence
= &lt;span&gt;&lt;font color="#2b91af"&gt;Regex&lt;/font&gt;&lt;/span&gt;.Replace(content,&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#a31515"&gt;@&amp;quot;&amp;lt;(.|\n)*?&amp;gt;&amp;quot;&lt;/font&gt;&lt;/span&gt;,&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;
match =&amp;gt; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #e5e5e5"&gt;&amp;quot;
&amp;quot;&lt;/font&gt;&lt;/span&gt;.PadRight(match.Length));&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; tmpContent
= content;&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
Loop through each link term, search for matches. Save each of them into a new collection&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
We're going to use the results to sort the matches in decending order by location.
That&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
way we can perform the replacements w/o moving the starting location of the other
replacements.&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;foreach&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt; linkRow &lt;span&gt;&lt;font color="#0000ff"&gt;in&lt;/font&gt;&lt;/span&gt; LinkWords)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt; allMatches
= &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;Match&lt;/font&gt;&lt;/span&gt;&amp;gt;();&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#2b91af"&gt;MatchCollection&lt;/font&gt;&lt;/span&gt; matches
= &lt;span&gt;&lt;font color="#2b91af"&gt;Regex&lt;/font&gt;&lt;/span&gt;.Matches(newSentence, linkRow.LinkTerm, &lt;span&gt;&lt;font color="#2b91af"&gt;RegexOptions&lt;/font&gt;&lt;/span&gt;.IgnoreCase);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;foreach&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#2b91af"&gt;Match&lt;/font&gt;&lt;/span&gt; match &lt;span&gt;&lt;font color="#0000ff"&gt;in&lt;/font&gt;&lt;/span&gt; matches)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;
allMatches.Add(match);&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt; orderedMatches
= &lt;span&gt;&lt;font color="#0000ff"&gt;from&lt;/font&gt;&lt;/span&gt; m &lt;span&gt;&lt;font color="#0000ff"&gt;in&lt;/font&gt;&lt;/span&gt; allMatches&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;orderby&lt;/font&gt;&lt;/span&gt; m.Index &lt;span&gt;&lt;font color="#0000ff"&gt;descending&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;select&lt;/font&gt;&lt;/span&gt; m;&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
General idea is to grab all of the text following the match, get the newly&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
link word w/html markup and insert it before the this text. Then truncate&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
the original content to remove everything from the starting position of the&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
match to the end of file - this is basically done so I don't have to track&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
the current position within the file. After we're done with the loop we&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
insert anything that's left to the beginning of the new string.&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;foreach&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#2b91af"&gt;Match&lt;/font&gt;&lt;/span&gt; item &lt;span&gt;&lt;font color="#0000ff"&gt;in&lt;/font&gt;&lt;/span&gt; orderedMatches)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;
{&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; endOfMatchedStringToEOF
= tmpContent.Substring(item.Index + item.Length);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;
result.Insert(0, GetAutolinkText(linkRow, item.Value) + endOfMatchedStringToEOF);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;
tmpContent = tmpContent.Substring(0, item.Index);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;
}&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result.Insert(0,
tmpContent);&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt; result.ToString();&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;summary&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt; Get
the replacement text.&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;font color="#808080"&gt;&lt;span&gt;&amp;lt;param
name=&lt;/span&gt;&lt;span&gt;&amp;quot;token&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;Word
token&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;font color="#808080"&gt;&lt;span&gt;&amp;lt;param
name=&lt;/span&gt;&lt;span&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;Original
content&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;returns&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;Empty
string if no replacement&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/returns&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;developer&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;Paul
Mrozowski&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/developer&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#808080"&gt;///&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;created&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;07/08/2008&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#808080"&gt;&amp;lt;/created&amp;gt;&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; GetAutolinkText(&lt;span&gt;&lt;font color="#2b91af"&gt;Term&lt;/font&gt;&lt;/span&gt; linkTo, &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; match)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; newWord
= match;&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.m_linkStyle.Length
== 0)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;
newWord = &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;.Format(&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #e5e5e5"&gt;&amp;quot;&amp;lt;a
href='{0}' &amp;quot;&lt;/font&gt;&lt;/span&gt;, linkTo.Url);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;else&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;
newWord = &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;.Format(&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #e5e5e5"&gt;&amp;quot;&amp;lt;a
class='{0}' href='{1}' &amp;quot;&lt;/font&gt;&lt;/span&gt;, 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.LinkStyle, 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;
linkTo.Url);&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt; ((linkTo.Target
?? &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #e5e5e5"&gt;&amp;quot;&amp;quot;&lt;/font&gt;&lt;/span&gt;).Length
&amp;gt; 0)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;
newWord += &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;.Format(&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #e5e5e5"&gt;&amp;quot;target='{0}'
&amp;quot;&lt;/font&gt;&lt;/span&gt;, linkTo.Target);&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffffbf"&gt;//
We pass in the original match term to maintain its case (the initial match was case-insensitive).&lt;/font&gt;&lt;/span&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; newWord += &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;.Format(&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #e5e5e5"&gt;&amp;quot;&amp;gt;{0}&amp;lt;/a&amp;gt;&amp;quot;&lt;/font&gt;&lt;/span&gt;,
match);&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt; newWord;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;
}&lt;/font&gt;&lt;/font&gt;
&lt;br /&gt;
&lt;/pre&gt;
&lt;p&gt;
Usage is simple – create a list of terms that you want linked (along with the URL,
style (if any), and target) and pass it to the AutoLinker class, then call AutoLink
with your source text. It will return the text with the links embedded in it. Here’s
a sample from a console application:
&lt;/p&gt;
&lt;pre&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 12pt"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; Main(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;[]
args)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt; terms
= &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;Term&lt;/font&gt;&lt;/span&gt;&amp;gt;();&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; terms.Add(&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#2b91af"&gt;Term&lt;/font&gt;&lt;/span&gt;()
{ LinkTerm = &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #e5e5e5"&gt;&amp;quot;Hello&amp;quot;&lt;/font&gt;&lt;/span&gt;,
Target = &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #e5e5e5"&gt;&amp;quot;_blank&amp;quot;&lt;/font&gt;&lt;/span&gt;,
Url = &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #e5e5e5"&gt;&amp;quot;http://www.rcs-solutions.com&amp;quot;&lt;/font&gt;&lt;/span&gt; });&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; sentence
= &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #e5e5e5"&gt;&amp;quot;Why,
hello! This is a sentence where I'm going to link to the word \&amp;quot;hello\&amp;quot;.&amp;quot;&lt;/font&gt;&lt;/span&gt;;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#2b91af"&gt;Console&lt;/font&gt;&lt;/span&gt;.Write(sentence);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt; linker
= &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;font color="#2b91af"&gt;AutoLinker&lt;/font&gt;&lt;/span&gt;(terms);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#2b91af"&gt;Console&lt;/font&gt;&lt;/span&gt;.Write(linker.AutoLink(sentence));&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span&gt;&lt;font color="#2b91af"&gt;Console&lt;/font&gt;&lt;/span&gt;.ReadKey();&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=c3498c80-09ad-42a8-a4e0-6e7f03caceb0" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,c3498c80-09ad-42a8-a4e0-6e7f03caceb0.aspx</comments>
      <category>.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=59948bb3-a579-4698-a535-e7d8ea4e58e6</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,59948bb3-a579-4698-a535-e7d8ea4e58e6.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,59948bb3-a579-4698-a535-e7d8ea4e58e6.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=59948bb3-a579-4698-a535-e7d8ea4e58e6</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <script type="text/javascript" src="/scripts/shCore.js">
        </script>
        <script type="text/javascript" src="/scripts/shBrushVFP.js">
        </script>
        <link rel="stylesheet" type="text/css" href="/styles/shCore.css" />
        <link rel="stylesheet" type="text/css" href="/styles/shThemeDefault.css" />
        <p>
While I was originally planning my jQuery for VFP developer session for South West
Fox, I had planning on showing all of the demos hosted inside of a browser hosted
in a VFP form (which I did). I also planned on having a link available on each page
which would slide out color-coded samples of the code actually running in the page.
As part of that, I created a syntax highlighter brush for VFP to work with Alex Gorbatchev’s
SynaxHighlighter (since none seemed to be available) – it’s a Javascript based syntax
highlighter that lets you embed code samples in things like blog pages and it will
color-code the syntax. I ended up deciding that it didn’t really work too well in
the context of a session, so I scrapped that portion of my demos. 
</p>
        <p>
You can download it from <a href="http://www.rcs-solutions.com/Download.ashx?File=shBrushVFP.js">here</a></p>
        <p>
 <script type="text/javascript">
		SyntaxHighlighter.all();
	</script><script type="syntaxhighlighter" class="brush: vfp"><![CDATA[
DEFINE CLASS SampleCode AS Custom
   oConfig = NULL
   cLastError = ""
   lConnected = .F.
   ******************************************************************
   *  FUNCTION NAME: Init
   *	
   *  AUTHOR, DATE:
   *	  Paul Mrozowski, 11/18/2010  
   *  PROCEDURE DESCRIPTION:
   *	  Set things up.
   *  INPUT PARAMETERS:
   *	  None
   *  OUTPUT PARAMETERS:
   *	  None
   ******************************************************************
   FUNCTION Init()      
      This.OpenTables()
      This.GetConfig()
   ENDFUNC

ENDDEFINE
]]></script>Alex’s
site includes more information about use – just make sure you reference the new brush
from within your webpage:
</p>
        <p>
&lt;script type="text/javascript" src="/scripts/shBrushVFP.js"&gt;&lt;/script&gt;
</p>
        <p>
 
</p>
        <p>
 
</p>
        <p>
          <strong>Links</strong>
        </p>
        <p>
          <a title="http://alexgorbatchev.com/SyntaxHighlighter/" href="http://alexgorbatchev.com/SyntaxHighlighter/">http://alexgorbatchev.com/SyntaxHighlighter/</a>
          <br />
          <a href="http://www.rcs-solutions.com/Download.ashx?File=shBrushVFP.js">http://www.rcs-solutions.com/Download.ashx?File=shBrushVFP.js</a>
        </p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=59948bb3-a579-4698-a535-e7d8ea4e58e6" />
      </body>
      <title>Syntax Highlighter Brush for VFP</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,59948bb3-a579-4698-a535-e7d8ea4e58e6.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2010/11/20/SyntaxHighlighterBrushForVFP.aspx</link>
      <pubDate>Sat, 20 Nov 2010 02:06:32 GMT</pubDate>
      <description>&lt;script type="text/javascript" src="/scripts/shCore.js"&gt;&lt;/script&gt;&lt;script type="text/javascript" src="/scripts/shBrushVFP.js"&gt;&lt;/script&gt;
&lt;link rel="stylesheet" type="text/css" href="/styles/shCore.css" /&gt;
&lt;link rel="stylesheet" type="text/css" href="/styles/shThemeDefault.css" /&gt;
&lt;p&gt;
While I was originally planning my jQuery for VFP developer session for South West
Fox, I had planning on showing all of the demos hosted inside of a browser hosted
in a VFP form (which I did). I also planned on having a link available on each page
which would slide out color-coded samples of the code actually running in the page.
As part of that, I created a syntax highlighter brush for VFP to work with Alex Gorbatchev’s
SynaxHighlighter (since none seemed to be available) – it’s a Javascript based syntax
highlighter that lets you embed code samples in things like blog pages and it will
color-code the syntax. I ended up deciding that it didn’t really work too well in
the context of a session, so I scrapped that portion of my demos. 
&lt;/p&gt;
&lt;p&gt;
You can download it from &lt;a href="http://www.rcs-solutions.com/Download.ashx?File=shBrushVFP.js"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;#160;&lt;script type="text/javascript"&gt;
		SyntaxHighlighter.all();
	&lt;/script&gt;
&lt;script type="syntaxhighlighter" class="brush: vfp"&gt;&lt;![CDATA[
DEFINE CLASS SampleCode AS Custom
   oConfig = NULL
   cLastError = ""
   lConnected = .F.
   ******************************************************************
   *  FUNCTION NAME: Init
   *	
   *  AUTHOR, DATE:
   *	  Paul Mrozowski, 11/18/2010  
   *  PROCEDURE DESCRIPTION:
   *	  Set things up.
   *  INPUT PARAMETERS:
   *	  None
   *  OUTPUT PARAMETERS:
   *	  None
   ******************************************************************
   FUNCTION Init()      
      This.OpenTables()
      This.GetConfig()
   ENDFUNC

ENDDEFINE
]]&gt;&lt;/script&gt;Alex’s
site includes more information about use – just make sure you reference the new brush
from within your webpage:
&lt;/p&gt;
&lt;p&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/scripts/shBrushVFP.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Links&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://alexgorbatchev.com/SyntaxHighlighter/" href="http://alexgorbatchev.com/SyntaxHighlighter/"&gt;http://alexgorbatchev.com/SyntaxHighlighter/&lt;/a&gt;
&lt;br /&gt;
&lt;a href="http://www.rcs-solutions.com/Download.ashx?File=shBrushVFP.js"&gt;http://www.rcs-solutions.com/Download.ashx?File=shBrushVFP.js&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=59948bb3-a579-4698-a535-e7d8ea4e58e6" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,59948bb3-a579-4698-a535-e7d8ea4e58e6.aspx</comments>
      <category>Javascript</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=867fb033-ea32-4918-9aac-1b62c1bcdcf0</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,867fb033-ea32-4918-9aac-1b62c1bcdcf0.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,867fb033-ea32-4918-9aac-1b62c1bcdcf0.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=867fb033-ea32-4918-9aac-1b62c1bcdcf0</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve updated and tested my plug-ins for CodeRush/Refactor! to make sure they work
in Visual Studio 2010 and with the new version of the product. All of them include
all the source code and a compiled DLL. Just copy the plug-ins into your \Users\UserName\Documents\DevExpress\IDE
Tools\Community\PlugIns folder. 
</p>
        <h4>Translate
</h4>
        <p>
Have some sample code in C# that you’d rather see in VB? Or vice-versa? Translate
converts the code under the current cursor position to the equivalent version. 
</p>
        <p>
          <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/Windows-Live-Writer/4102fb8b1288_F63B/image_12.png" width="887" height="272" />
        </p>
        <p>
You can find more information about this plug-in here:
</p>
        <p>
          <a title="http://www.rcs-solutions.com/blog/2008/08/17/TranslateCToVBNETOrViceversaUsingCodeRush.aspx" href="http://www.rcs-solutions.com/blog/2008/08/17/TranslateCToVBNETOrViceversaUsingCodeRush.aspx">http://www.rcs-solutions.com/blog/2008/08/17/TranslateCToVBNETOrViceversaUsingCodeRush.aspx</a>
        </p>
        <p>
And you can download it from here:
</p>
        <p>
          <a title="http://www.rcs-solutions.com/Download.ashx?File=CR_Translator2010.zip" href="http://www.rcs-solutions.com/Download.ashx?File=CR_Translator2010.zip">http://www.rcs-solutions.com/Download.ashx?File=CR_Translator2010.zip</a>
        </p>
        <p>
 
</p>
        <h4>Collapse XML
</h4>
        <p>
This plug-in collapses multi-line XML comments into one line, so this:
</p>
        <p>
 
</p>
        <p>
          <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/Windows-Live-Writer/4102fb8b1288_F63B/image_9.png" width="519" height="181" />
        </p>
        <p>
Becomes this by hitting the Refactor key:
</p>
        <p>
          <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/Windows-Live-Writer/4102fb8b1288_F63B/image_8.png" width="637" height="150" />
        </p>
        <p>
You can find more information about this plug-in here:
</p>
        <p>
          <a title="http://www.rcs-solutions.com/blog/2008/08/08/CollapsingXMLCommentTags.aspx" href="http://www.rcs-solutions.com/blog/2008/08/08/CollapsingXMLCommentTags.aspx">http://www.rcs-solutions.com/blog/2008/08/08/CollapsingXMLCommentTags.aspx</a>
        </p>
        <p>
And download it from here:
</p>
        <p>
          <a title="http://www.rcs-solutions.com/Download.ashx?File=DX_CollapseComments.zip" href="http://www.rcs-solutions.com/Download.ashx?File=DX_CollapseComments.zip">http://www.rcs-solutions.com/Download.ashx?File=DX_CollapseComments.zip</a>
        </p>
        <p>
 
</p>
        <h4>Developer Initials
</h4>
        <p>
I made a few changes based on feedback to the Developer Initials plug-in. You can
now configure the format of the comment added.
</p>
        <p>
          <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/Windows-Live-Writer/4102fb8b1288_F63B/image_3.png" width="667" height="474" />
        </p>
        <p>
You can find more information about this plug-in here:
</p>
        <p>
          <a title="http://www.rcs-solutions.com/blog/2008/08/06/CodeRushPluginDeveloperInitials.aspx" href="http://www.rcs-solutions.com/blog/2008/08/06/CodeRushPluginDeveloperInitials.aspx">http://www.rcs-solutions.com/blog/2008/08/06/CodeRushPluginDeveloperInitials.aspx</a>
        </p>
        <p>
And download it from here:
</p>
        <p>
          <a title="http://www.rcs-solutions.com/Download.ashx?File=CR_Initials2010.zip" href="http://www.rcs-solutions.com/Download.ashx?File=CR_Initials2010.zip">http://www.rcs-solutions.com/Download.ashx?File=CR_Initials2010.zip</a>
        </p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=867fb033-ea32-4918-9aac-1b62c1bcdcf0" />
      </body>
      <title>Updated CodeRush/Refactor! Plug-ins</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,867fb033-ea32-4918-9aac-1b62c1bcdcf0.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2010/11/16/UpdatedCodeRushRefactorPlugins.aspx</link>
      <pubDate>Tue, 16 Nov 2010 22:54:15 GMT</pubDate>
      <description>&lt;p&gt;
I’ve updated and tested my plug-ins for CodeRush/Refactor! to make sure they work
in Visual Studio 2010 and with the new version of the product. All of them include
all the source code and a compiled DLL. Just copy the plug-ins into your \Users\UserName\Documents\DevExpress\IDE
Tools\Community\PlugIns folder. 
&lt;/p&gt;
&lt;h4&gt;Translate
&lt;/h4&gt;
&lt;p&gt;
Have some sample code in C# that you’d rather see in VB? Or vice-versa? Translate
converts the code under the current cursor position to the equivalent version. 
&lt;/p&gt;
&lt;p&gt;
&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/Windows-Live-Writer/4102fb8b1288_F63B/image_12.png" width="887" height="272" /&gt;
&lt;/p&gt;
&lt;p&gt;
You can find more information about this plug-in here:
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://www.rcs-solutions.com/blog/2008/08/17/TranslateCToVBNETOrViceversaUsingCodeRush.aspx" href="http://www.rcs-solutions.com/blog/2008/08/17/TranslateCToVBNETOrViceversaUsingCodeRush.aspx"&gt;http://www.rcs-solutions.com/blog/2008/08/17/TranslateCToVBNETOrViceversaUsingCodeRush.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
And you can download it from here:
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://www.rcs-solutions.com/Download.ashx?File=CR_Translator2010.zip" href="http://www.rcs-solutions.com/Download.ashx?File=CR_Translator2010.zip"&gt;http://www.rcs-solutions.com/Download.ashx?File=CR_Translator2010.zip&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;h4&gt;Collapse XML
&lt;/h4&gt;
&lt;p&gt;
This plug-in collapses multi-line XML comments into one line, so this:
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/Windows-Live-Writer/4102fb8b1288_F63B/image_9.png" width="519" height="181" /&gt;
&lt;/p&gt;
&lt;p&gt;
Becomes this by hitting the Refactor key:
&lt;/p&gt;
&lt;p&gt;
&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/Windows-Live-Writer/4102fb8b1288_F63B/image_8.png" width="637" height="150" /&gt;
&lt;/p&gt;
&lt;p&gt;
You can find more information about this plug-in here:
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://www.rcs-solutions.com/blog/2008/08/08/CollapsingXMLCommentTags.aspx" href="http://www.rcs-solutions.com/blog/2008/08/08/CollapsingXMLCommentTags.aspx"&gt;http://www.rcs-solutions.com/blog/2008/08/08/CollapsingXMLCommentTags.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
And download it from here:
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://www.rcs-solutions.com/Download.ashx?File=DX_CollapseComments.zip" href="http://www.rcs-solutions.com/Download.ashx?File=DX_CollapseComments.zip"&gt;http://www.rcs-solutions.com/Download.ashx?File=DX_CollapseComments.zip&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;h4&gt;Developer Initials
&lt;/h4&gt;
&lt;p&gt;
I made a few changes based on feedback to the Developer Initials plug-in. You can
now configure the format of the comment added.
&lt;/p&gt;
&lt;p&gt;
&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/Windows-Live-Writer/4102fb8b1288_F63B/image_3.png" width="667" height="474" /&gt;
&lt;/p&gt;
&lt;p&gt;
You can find more information about this plug-in here:
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://www.rcs-solutions.com/blog/2008/08/06/CodeRushPluginDeveloperInitials.aspx" href="http://www.rcs-solutions.com/blog/2008/08/06/CodeRushPluginDeveloperInitials.aspx"&gt;http://www.rcs-solutions.com/blog/2008/08/06/CodeRushPluginDeveloperInitials.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
And download it from here:
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://www.rcs-solutions.com/Download.ashx?File=CR_Initials2010.zip" href="http://www.rcs-solutions.com/Download.ashx?File=CR_Initials2010.zip"&gt;http://www.rcs-solutions.com/Download.ashx?File=CR_Initials2010.zip&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=867fb033-ea32-4918-9aac-1b62c1bcdcf0" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,867fb033-ea32-4918-9aac-1b62c1bcdcf0.aspx</comments>
      <category>CodeRush</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=fef6ca36-4faa-4b5e-b76c-a1052203b701</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,fef6ca36-4faa-4b5e-b76c-a1052203b701.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,fef6ca36-4faa-4b5e-b76c-a1052203b701.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=fef6ca36-4faa-4b5e-b76c-a1052203b701</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve recently started a new ASP.NET MVC project and ran across what is a really common
need: I wanted a drop-down list that contained the same items but that I could re-use
a few times on the same page. In “classic” ASP.NET I’d just create a user control,
expose a property or two to allow me to handle data binding to this list and be done
with it. Heck, in my case it didn’t even need to be data driven – it was a static
list of items (like a drop-down list of states). I could do this inside of a view
then populate the list but I didn’t want to tie this to a particular view, I wanted
it available from any page.
</p>
        <p>
OK, so how do you do this in ASP.NET MVC? It doesn’t have the same control model,
so I wasn’t entirely sure what the best way to handle this was. 
</p>
        <p>
Some things I considered:
</p>
        <ul>
          <li>
Create my own “helper” that generated all the HTML for it. That sounded like way more
work than I wanted to do. 
</li>
          <li>
Create my own helper but somehow leverage the built-in DropDownList to do the heavy
lifting. I started looking at this, didn’t see immediately how I would hook everything
together so I skipped it. 
</li>
          <li>
Create a partial view. This was actually my first thought but I couldn’t figure out
how I’d handle being able to “name” the DropDownList in the partial view (since I
needed to have multiple copies of the control on the same page and I wanted each to
have it’s own unique name and bind to a different property in my ViewModel. Mind you,
at this point I have like 3 hours experience with MVC. 
</li>
        </ul>
        <p>
 
</p>
        <p>
Honestly, I wasn’t happy with any of them. They all seemed like more work than I was
expecting (but at this point I wasn’t sure how much work was really required). I did
a bunch of Google searches and finally ran across this question on Stack Overflow:
</p>
        <p>
          <a title="http://stackoverflow.com/questions/289048/asp-net-mvc-us-state-drop-down-list" href="http://stackoverflow.com/questions/289048/asp-net-mvc-us-state-drop-down-list">http://stackoverflow.com/questions/289048/asp-net-mvc-us-state-drop-down-list</a>
        </p>
        <p>
That was exactly what I was looking for. You create a simple static method that returns
an IDictionary and then another one which returns a SelectList of your IDictionary
so that it can be used by the framework.
</p>
        <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
          <div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span>
            <span style="color: #2b91af">ItemScores</span>
            <br />
{ 
<br />
    <span style="color: #0000ff">public</span><span style="color: #0000ff">static</span><span style="color: #0000ff">readonly</span><span style="color: #2b91af">IDictionary</span>&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">string</span>&gt;
Scores = <span style="color: #0000ff">new</span><span style="color: #2b91af">Dictionary</span>&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">string</span>&gt;() 
<br />
        { 
<br />
            {<span style="background: #e5e5e5">"5
- Best"</span>, <span style="background: #e5e5e5">"1"}</span>, 
<br />
            {<span style="background: #e5e5e5">"4"</span>, <span style="background: #e5e5e5">"4"}</span>, 
<br />
            {<span style="background: #e5e5e5">"3
- Average"</span>, <span style="background: #e5e5e5">"3"}</span>, 
<br />
            {<span style="background: #e5e5e5">"2"</span>, <span style="background: #e5e5e5">"2"}</span>, 
<br />
            {<span style="background: #e5e5e5">"1
- Bad"</span>, <span style="background: #e5e5e5">"1"}</span><br />
        }; 
<br /><br />
    <span style="color: #0000ff">public</span><span style="color: #0000ff">static</span> SelectList
ScoreList 
<br />
    { 
<br />
        <span style="color: #0000ff">get</span> { <span style="color: #0000ff">return</span><span style="color: #0000ff">new</span> SelectList(Scores, <span style="background: #e5e5e5">"Value"</span>, <span style="background: #e5e5e5">"Key"</span>);
} 
<br />
    } 
<br />
}
</div>
        </div>
        <p>
Then from within your view you use the standard Html helper:
</p>
        <pre>
          <p>
&lt;%: Html.DropDownList("OverallScore", ItemScores.ScoreList) %&gt;
</p>
        </pre>
        <p>
That was a lot closer to what I was expecting. I expect to revisit this topic again
as soon as I need a slightly more complex component, but for right now this works
well for me.
</p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=fef6ca36-4faa-4b5e-b76c-a1052203b701" />
      </body>
      <title>Creating a Simple &amp;amp; Re-Usable Dropdownlist/Combo in ASP.NET MVC</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,fef6ca36-4faa-4b5e-b76c-a1052203b701.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2010/10/09/CreatingASimpleAmpReUsableDropdownlistComboInASPNETMVC.aspx</link>
      <pubDate>Sat, 09 Oct 2010 15:53:27 GMT</pubDate>
      <description>&lt;p&gt;
I’ve recently started a new ASP.NET MVC project and ran across what is a really common
need: I wanted a drop-down list that contained the same items but that I could re-use
a few times on the same page. In “classic” ASP.NET I’d just create a user control,
expose a property or two to allow me to handle data binding to this list and be done
with it. Heck, in my case it didn’t even need to be data driven – it was a static
list of items (like a drop-down list of states). I could do this inside of a view
then populate the list but I didn’t want to tie this to a particular view, I wanted
it available from any page.
&lt;/p&gt;
&lt;p&gt;
OK, so how do you do this in ASP.NET MVC? It doesn’t have the same control model,
so I wasn’t entirely sure what the best way to handle this was. 
&lt;/p&gt;
&lt;p&gt;
Some things I considered:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Create my own “helper” that generated all the HTML for it. That sounded like way more
work than I wanted to do. 
&lt;/li&gt;
&lt;li&gt;
Create my own helper but somehow leverage the built-in DropDownList to do the heavy
lifting. I started looking at this, didn’t see immediately how I would hook everything
together so I skipped it. 
&lt;/li&gt;
&lt;li&gt;
Create a partial view. This was actually my first thought but I couldn’t figure out
how I’d handle being able to “name” the DropDownList in the partial view (since I
needed to have multiple copies of the control on the same page and I wanted each to
have it’s own unique name and bind to a different property in my ViewModel. Mind you,
at this point I have like 3 hours experience with MVC. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
Honestly, I wasn’t happy with any of them. They all seemed like more work than I was
expecting (but at this point I wasn’t sure how much work was really required). I did
a bunch of Google searches and finally ran across this question on Stack Overflow:
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://stackoverflow.com/questions/289048/asp-net-mvc-us-state-drop-down-list" href="http://stackoverflow.com/questions/289048/asp-net-mvc-us-state-drop-down-list"&gt;http://stackoverflow.com/questions/289048/asp-net-mvc-us-state-drop-down-list&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
That was exactly what I was looking for. You create a simple static method that returns
an IDictionary and then another one which returns a SelectList of your IDictionary
so that it can be used by the framework.
&lt;/p&gt;
&lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;
&lt;div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ItemScores&lt;/span&gt; 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;
Scores = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;() 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;span style="background: #e5e5e5"&gt;&amp;quot;5
- Best&amp;quot;&lt;/span&gt;, &lt;span style="background: #e5e5e5"&gt;&amp;quot;1&amp;quot;}&lt;/span&gt;, 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;span style="background: #e5e5e5"&gt;&amp;quot;4&amp;quot;&lt;/span&gt;, &lt;span style="background: #e5e5e5"&gt;&amp;quot;4&amp;quot;}&lt;/span&gt;, 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;span style="background: #e5e5e5"&gt;&amp;quot;3
- Average&amp;quot;&lt;/span&gt;, &lt;span style="background: #e5e5e5"&gt;&amp;quot;3&amp;quot;}&lt;/span&gt;, 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;span style="background: #e5e5e5"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;, &lt;span style="background: #e5e5e5"&gt;&amp;quot;2&amp;quot;}&lt;/span&gt;, 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;span style="background: #e5e5e5"&gt;&amp;quot;1
- Bad&amp;quot;&lt;/span&gt;, &lt;span style="background: #e5e5e5"&gt;&amp;quot;1&amp;quot;}&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }; 
&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; SelectList
ScoreList 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; { 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SelectList(Scores, &lt;span style="background: #e5e5e5"&gt;&amp;quot;Value&amp;quot;&lt;/span&gt;, &lt;span style="background: #e5e5e5"&gt;&amp;quot;Key&amp;quot;&lt;/span&gt;);
} 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; } 
&lt;br /&gt;
}
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Then from within your view you use the standard Html helper:
&lt;/p&gt;
&lt;pre&gt;
&lt;p&gt;
&amp;lt;%: Html.DropDownList(&amp;quot;OverallScore&amp;quot;, ItemScores.ScoreList) %&amp;gt;
&lt;/p&gt;
&lt;/pre&gt;
&lt;p&gt;
That was a lot closer to what I was expecting. I expect to revisit this topic again
as soon as I need a slightly more complex component, but for right now this works
well for me.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=fef6ca36-4faa-4b5e-b76c-a1052203b701" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,fef6ca36-4faa-4b5e-b76c-a1052203b701.aspx</comments>
      <category>ASP.NET MVC</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=b5fe0773-5338-44b0-abc6-92e41f252101</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,b5fe0773-5338-44b0-abc6-92e41f252101.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,b5fe0773-5338-44b0-abc6-92e41f252101.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=b5fe0773-5338-44b0-abc6-92e41f252101</wfw:commentRss>
      <slash:comments>7</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A common pattern you tend to find in maintenance forms is the ability to open another
form so you can add/edit/maintain some list of items. When you return back to the
calling form you want to refresh a combo or grid to reflect the changes. The way most
of us do this is to make the maintenance form modal. When you call it, code execution
stops until the form is released. That works but it can break down if you find yourself
more than 1 level deep in maintenance forms – the user can’t easily move windows out
of the way to see information and you’ll occasionally find that the wrong form has
somehow gotten focus leaving you stuck (unable to get focus back to the correct form). 
</p>
        <p>
Here’s an example. The user starts off on the Client Maintenance form, then clicks
on the Commissary button (military grocery store) to select which stores are associated
with this client. Then they click on the Commissary button again if they want to add/edit
a new store. When they close this form we want to refresh the second form.
</p>
        <p>
 
</p>
        <p>
          <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/AlternativetoModalVFPForms_A10D/image_3.png" width="640" height="448" />
        </p>
        <p>
Again, the normal way you might do this is to make the third form modal.
</p>
        <pre style="background: #eeeeee">DO FORM CommissaryMaintenance
* When the form is closed the code below is run which saves and refreshes
* the options shown.
ThisForm.SaveAndRefresh()</pre>
        <p>
An alternative to this code (and making the form modal) is to do something like this
instead:
</p>
        <pre style="background: #eeeeee">DO FORM CommissaryMaintenance NAME loForm
BINDEVENT(loForm, “Destroy”, ThisForm, “SaveAndRefresh”)</pre>
        <p>
Now the form can stay modeless. We’re taking advantage of VFP’s BINDEVENT command.
When the form is closed and the Destroy() event fired we’ll fire the SaveAndRefresh()
method which refreshes the form. It’s simple and avoids the problems mentioned above. 
</p>
        <p>
One suggestion is to add code in the calling form to set focus back to itself (in
case you are mixing and matching modal and non-modal forms). Ex. in the SaveAndRefresh()
method you might want to do something like this:
</p>
        <pre style="background: #eeeeee">ThisForm.grdList.SetFocus()</pre>
        <p>
That will ensure that your form actually gets focus and back where the user is expecting
to be.
</p>
        <p>
This all works great, but what if you want to update the form as new items are add,
not just when the form closes? If you modify the maintenance form to call an empty
method after a successful save, ex. create a method named SaveSuccessful() you can
now bind to this method instead of Destroy().
</p>
        <pre style="background: #eeeeee">BINDEVENT(loForm, “SaveSuccessful”, ThisForm, “SaveAndRefresh”)</pre>
        <p>
With only an extra line or two of code you can get rid of the modal form and still
have your calling for get easily updated/refreshed when things are changed.
</p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=b5fe0773-5338-44b0-abc6-92e41f252101" />
      </body>
      <title>Alternative to Modal VFP Forms</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,b5fe0773-5338-44b0-abc6-92e41f252101.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2010/07/21/AlternativeToModalVFPForms.aspx</link>
      <pubDate>Wed, 21 Jul 2010 21:15:53 GMT</pubDate>
      <description>&lt;p&gt;
A common pattern you tend to find in maintenance forms is the ability to open another
form so you can add/edit/maintain some list of items. When you return back to the
calling form you want to refresh a combo or grid to reflect the changes. The way most
of us do this is to make the maintenance form modal. When you call it, code execution
stops until the form is released. That works but it can break down if you find yourself
more than 1 level deep in maintenance forms – the user can’t easily move windows out
of the way to see information and you’ll occasionally find that the wrong form has
somehow gotten focus leaving you stuck (unable to get focus back to the correct form). 
&lt;/p&gt;
&lt;p&gt;
Here’s an example. The user starts off on the Client Maintenance form, then clicks
on the Commissary button (military grocery store) to select which stores are associated
with this client. Then they click on the Commissary button again if they want to add/edit
a new store. When they close this form we want to refresh the second form.
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/AlternativetoModalVFPForms_A10D/image_3.png" width="640" height="448" /&gt; 
&lt;/p&gt;
&lt;p&gt;
Again, the normal way you might do this is to make the third form modal.
&lt;/p&gt;
&lt;pre style="background: #eeeeee"&gt;DO FORM CommissaryMaintenance
* When the form is closed the code below is run which saves and refreshes
* the options shown.
ThisForm.SaveAndRefresh()&lt;/pre&gt;
&lt;p&gt;
An alternative to this code (and making the form modal) is to do something like this
instead:
&lt;/p&gt;
&lt;pre style="background: #eeeeee"&gt;DO FORM CommissaryMaintenance NAME loForm
BINDEVENT(loForm, “Destroy”, ThisForm, “SaveAndRefresh”)&lt;/pre&gt;
&lt;p&gt;
Now the form can stay modeless. We’re taking advantage of VFP’s BINDEVENT command.
When the form is closed and the Destroy() event fired we’ll fire the SaveAndRefresh()
method which refreshes the form. It’s simple and avoids the problems mentioned above. 
&lt;/p&gt;
&lt;p&gt;
One suggestion is to add code in the calling form to set focus back to itself (in
case you are mixing and matching modal and non-modal forms). Ex. in the SaveAndRefresh()
method you might want to do something like this:
&lt;/p&gt;
&lt;pre style="background: #eeeeee"&gt;ThisForm.grdList.SetFocus()&lt;/pre&gt;
&lt;p&gt;
That will ensure that your form actually gets focus and back where the user is expecting
to be.
&lt;/p&gt;
&lt;p&gt;
This all works great, but what if you want to update the form as new items are add,
not just when the form closes? If you modify the maintenance form to call an empty
method after a successful save, ex. create a method named SaveSuccessful() you can
now bind to this method instead of Destroy().
&lt;/p&gt;
&lt;pre style="background: #eeeeee"&gt;BINDEVENT(loForm, “SaveSuccessful”, ThisForm, “SaveAndRefresh”)&lt;/pre&gt;
&lt;p&gt;
With only an extra line or two of code you can get rid of the modal form and still
have your calling for get easily updated/refreshed when things are changed.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=b5fe0773-5338-44b0-abc6-92e41f252101" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,b5fe0773-5338-44b0-abc6-92e41f252101.aspx</comments>
      <category>VFP</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=c914191d-95fd-4d88-bcbb-11bb6b89761f</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,c914191d-95fd-4d88-bcbb-11bb6b89761f.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,c914191d-95fd-4d88-bcbb-11bb6b89761f.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=c914191d-95fd-4d88-bcbb-11bb6b89761f</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Interfaces are an integral part of .NET, yet a lot of new .NET developers (especially
those coming from weakly-typed languages, or languages where interfaces aren't supported)
have difficulty in understanding why they're needed and how (and when) they're used.
If you find yourself in that group you're in good company. It's not a difficult concept
but it can be a bit foreign to developers new to them. 
</p>
        <p>
Let's get the textbook definition out of the way, then take a look at what it really
means (and why you should even care). From Wikipedia: 
</p>
        <p>
"Interface generally refers to an abstraction that an entity provides of itself
to the outside. This separates the methods of external communication from internal
operation, and allows it to be internally modified without affecting the way outside
entities interact with it, as well as provide multiple abstractions of itself. It
may also provide a means of translation between entities which do not speak the same
language, such as between a human and a computer." 
</p>
        <p>
Hmm - OK. While technically correct that doesn't really help, does it? Did your eyes
glaze over like mine did while reading that? Maybe if we back up a bit and look at
what a class is we might be able to make some sense of this. 
</p>
        <h3>The Basics
</h3>
        <p>
A class is a collection of methods, properties, and events. It is assumed that each
of these methods, properties, and events "do something". At least in most
cases (we're going to ignore the idea of an abstract class for right now). So far,
so good. You can create a new instance of this class and do things with it, pass it
around to other classes as a parameter, etc. In a weakly typed language (also known
as a "dynamic language") you can pretty much pass any type of class around
without having to worry about the type - as long as your code doesn't try to access
a property or method that object doesn't have, you're good to go. The upside to this
is that it's pretty flexible. The downside to this is that mistakes aren't caught
at compile time - your app. just blows up at runtime (so you'd better test!). Strongly-typed
languages take a different approach: you must define the types that can be passed
as parameters to methods. That's OK as long as there is only one specific type your
method acts on, or the type you're passing in inherits from the base type of the parameter
- it's pretty straightforward. The upside is that mistakes (like trying to access
a property or method that doesn't exist) is caught at compile time. The downside is
that it's not as flexible as a dynamic language. 
</p>
        <p>
So what do I mean by "not as flexible"? On the surface it seems pretty reasonable
that a strongly-typed method only accepts specific types - how else would the compiler
(and you) know that it's safe to access a specific method or property? It doesn't.
It only can accept that specific type of class, or any subclass of that same type. 
</p>
        <p>
Why is it OK to accept a subclass of the type? Well, the compiler can be sure that
the subclass has the same exact properties &amp; methods as its parent (it doesn't
care if you add more of them or override the behavior). 
</p>
        <p>
But what if it doesn't? What if you had a class that wasn't of the correct type necssary
to pass into a method and it didn't inherit from that type either? Let's take a look
at an example of this. I wanted to keep it simple enough to understand, but have it
be a REAL scenario (not some contrived example). Those goals are a bit difficult to
balance so I error'd on the real scenario side of things. Hopefully it'll help you
understand WHY some things are the way they are in the framework in addition to understanding
interfaces. 
</p>
        <h3>A Real Example
</h3>
        <p>
For example, let's suppose we create a collection class that can have a collection
of objects (that are all of the same type) and we want to have a method which can
sort them. You want to write a generic Sort routine on your collection class that
can sort any kind of collection of objects, as long as they're the same type. The
first issue you'd run into is, "How do I generically create some code which can
compare ANY type?" Remember - you have to be able to compare strings, numbers,
date/times, maybe custom types someone may have created, etc. So it's not really possible
to be able to compare ANY type. You could cover the basic types and then require the
user to subclass your collection for any other custom types. It's a bit clunky, but
it would work. 
</p>
        <p>
What if, instead, we decided that we'd have another class responsible for doing the
sorting. We'd provide a default implementation and if you had your own custom types
that needed to be sorted you could pass in your own implementation. That's a bit better.
The developer would still need to subclass from our default implementation (since
we've still got the strongly-typed issues here - again, dynamic languages don't have
this "issue"). We could have the developer pass in their version of the
class which does the comparison into the Sort() method. The passed in class would
have a Compare() method and let's say it takes two parameters of the types of the
same type of object and returns an integer value indicating whether one of the objects
is less than, greater than, or equal to the other. 
</p>
        <p>
Let's take a look at what the code might look like for all of this: 
</p>
        <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
          <div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 400px; overflow: auto; padding-top: 2px">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span>
            <span style="color: #2b91af">Comparer</span>
            <br />
{ 
<br />
    <span style="color: #0000ff">public</span><span style="color: #0000ff">int</span> Compare(<span style="color: #0000ff">object</span> x, <span style="color: #0000ff">object</span> y) 
<br />
    { 
<br />
        <span style="background: #ffffbf">// Code
to do comparisons here </span><br />
    } 
<br />
} 
<br /><br /><span style="color: #0000ff">public</span><span style="color: #0000ff">class</span><span style="color: #2b91af">SampleArrayList</span><br />
{ 
<br />
    <span style="color: #0000ff">public</span><span style="color: #0000ff">virtual</span><span style="color: #0000ff">void</span> Sort() 
<br />
    { 
<br />
        <span style="color: #0000ff">this</span>.Sort(<span style="color: #0000ff">new</span><span style="color: #2b91af">Comparer</span>()); 
<br />
    } 
<br /><br />
    <span style="color: #0000ff">public</span><span style="color: #0000ff">virtual</span><span style="color: #0000ff">void</span> Sort(<span style="color: #2b91af">Comparer</span> comparer) 
<br />
    { 
<br />
        <span style="background: #ffffbf">// Do
sorting here. Call out to comparer object to do the actual comparison </span><br />
    } 
<br />
}
</div>
        </div>
        <p>
 
</p>
        <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
          <div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px">
            <span style="color: #2b91af">SampleArrayList</span> list
= <span style="color: #0000ff">new</span><span style="color: #2b91af">SampleArrayList</span>(); 
<br /><span style="background: #ffffbf">// Add items to the list </span><br />
list.Sort(); <span style="background: #ffffbf">// default implementation </span><br />
list.Sort(<span style="color: #0000ff">new</span> SomeComparerSubclass()); <span style="background: #ffffbf">//
A custom sort </span></div>
        </div>
        <p>
          <br />
That looks OK. If I wanted to create my own comparison class all I'd do is subclass
from Comparer and override Compare() with my own implementation. But let's take a
step back and think about this for a bit. If you create a new class and want a method
that can compare one instance of that class to another instance of it, where's the
best place for the code? Doing comparison's is a pretty fundamental capability of
a class - we do it all the time with string's, numbers, datetimes, etc. so clearly
it belongs with the class, right? Your only other alternative would be to put it into
another class that acts as a kind of "helper". That's effectively what we've
forced on any developers that want to use the sorting capability of our collection
for their own custom classes. They MUST create a helper class to do a comparison or
they'd all have to inherit from our Comparer class (and use it as their base object).
That might not be the end of the world but we're only talking about a single example
- there are a lot of other places where this scenario comes up. 
<br /><br />
OK, having to create another class which only does a comparison for a specific type
isn't all that great. Since it makes more sense to have a comparison handled by the
object being compared, let's say we add a method called CompareTo() to any class when
we want to be able to compare it against another instance. In our Comparer class we'll
call that method and, hey, our comparer class is now a bit more generic right? We
know that in .NET all objects inherit from "System.Object" so having our
Comparer class's Compare() method accept "objects" means we can use it with
ANY type. I don't actually have to create a new class for each and every item I'm
going to compare! But wait - we're STILL going to have the problem with calling the
CompareTo() method on our class in the collection; we're back to having to inherit
from a common base class.
</p>
        <p>
 
</p>
        <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
          <div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span>
            <span style="color: #2b91af">Comparer</span>
            <br />
{ 
<br />
    <span style="color: #0000ff">public</span><span style="color: #0000ff">int</span> Compare(<span style="color: #0000ff">object</span> x, <span style="color: #0000ff">object</span> y) 
<br />
    { 
<br />
        <span style="background: #ffffbf">// Code
to do comparisons here </span><br />
        <span style="color: #0000ff">return</span> x.CompareTo(y.CompareTo()); 
<br />
    } 
<br />
}
</div>
        </div>
        <br />
But now how can we call the CompareTo() method on those objects? How do we even know
if those objects have a CompareTo() method? Since .NET is strongly typed you can't
do this - it won't even compile. The class type "object" doesn't have a
"CompareTo" method. The .NET compiler knows that and it won't let you do
that. 
<br /><br />
This is begining to feel like a circular issue, isn't it? 
<p></p><h3>Breaking the Cycle
</h3><p>
OK, now what? Well, you could jump through a lot of hoops and use reflection to make
the method call for you. But it's a lot of work. In a dynamic language (such as Visual
FoxPro) code like that is perfectly valid - I can pass any object type into a method
like that and access any properties or methods and VFP doesn't care. If the object
doesn't have those properties or methods it will just blow up at runtime. I'm a good
developer so I won't pass in something that would blow up. .NET sucks - it makes things
so difficult. 
</p><p>
You're basically stuck at this point - you can't do what you'd like to do in .NET.
If .NET supported the idea of multiple inheritance (where class C could inherit from
Class A and from Class B at the same time), we'd be able to still make this work.
But it doesn't. 
</p><h3>Interfaces to the Rescue
</h3><p>
That's where interfaces come in (finally!). Let's take another stab at a more concrete
definition of an interface: An Interface is a definition of the types of properties,
events, and methods a class needs to implement. It's nothing more than a list of properties,
events, and methods (and the various types associated with them) that a class has
to have. While we can't inherit from multiple classes in .NET, we can inherit from
multiple interfaces. 
</p><p>
Getting back to our example, we could define an interface that consists of a public
method called CompareTo that accepts one parameter of the "System.Object"
type ("object" for short). This method needs to return an integer: Less
than zero means this instance is less than the object passed in, zero means it's equal,
and greater than one means it's greater than the passed in object. 
</p><p>
Here's what it might look like: 
</p><div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"><div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"><span style="color: #0000ff">public</span><span style="color: #0000ff">interface</span><span style="color: #2b91af">IComparable</span><br />
{ 
<br />
    <span style="color: #0000ff">int</span> CompareTo(<span style="color: #0000ff">object</span> obj); 
<br />
}
</div></div><p>
While we're at it, it seems like we might want to do something similar to our Comparer
class: 
</p><div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"><div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"><span style="color: #0000ff">public</span><span style="color: #0000ff">interface</span><span style="color: #2b91af">IComparer</span><br />
{ 
<br />
   <span style="color: #0000ff">int</span> Compare(<span style="color: #0000ff">object</span> x, <span style="color: #0000ff">object</span> y); 
<br />
}
</div></div><br /><br />
Now all we'd need to do is make sure that any class that we want to compare inherits
from the IComparer interface and then "implements" the specified properties,
methods, and events (PEM). That is, you need to make sure your class has all of the
same PEM's as the interface. Then you use the interface as the parameter type instead.
Since we can inherit multiple interfaces on a given type we have a way of giving our
classes the cameleon-like ability of appearing as exactly the right type to methods,
regardless of what class it really inherits from. We'd do the same thing for any class
which can compare two different classes. 
<br /><br />
So we can rewrite the above code: 
<p></p><div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"><div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"><span style="color: #0000ff">public</span><span style="color: #0000ff">class</span><span style="color: #2b91af">Comparer</span> : <span style="color: #2b91af">IComparer</span><br />
{ 
<br />
   <span style="color: #0000ff">public</span><span style="color: #0000ff">int</span> Compare(<span style="color: #0000ff">object</span> x, <span style="color: #0000ff">object</span> y) 
<br />
   { 
<br />
       <span style="background: #ffffbf">// Code here
which compares x to y and returns integer </span><br />
   } 
<br />
} 
<br /><br /><span style="color: #0000ff">public</span><span style="color: #0000ff">class</span><span style="color: #2b91af">MyCustomClass</span> : <span style="color: #2b91af">IComparable</span><br />
{ 
<br />
   <span style="color: #0000ff">public</span><span style="color: #0000ff">int</span> CompareTo(<span style="color: #0000ff">object</span> obj) 
<br />
   { 
<br />
   } 
<br />
   <span style="color: #0000ff">public</span><span style="color: #0000ff">int</span> CompareTo(<span style="color: #2b91af">MyCustomClass</span> obj) 
<br />
   { 
<br />
   } 
<br />
}
</div></div><p><br />
And we rewrite the Sort() method on our collection class SampleArrayList to accept
objects of type "IComparer" instead of "Comparer":  
<br /></p><div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"><div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"><span style="color: #0000ff">public</span><span style="color: #0000ff">void</span> Sort(<span style="color: #2b91af">IComparer</span> comparer) 
<br />
{ 
<br />
   <span style="background: #ffffbf">// Code here that iterates over the
collection and class Compare() </span><br />
   <span style="background: #ffffbf">// with two of the items in our internal
list. </span><br /><span style="background: #ffffbf">}</span></div></div><br /><br />
Suddenly all of this starts working again - you get compiler-time checking to make
sure things don't blow up, Intellisense works, etc. In fact the compiler verifies
that you have, in fact, done all of this correctly - if your classes don't implement
IComparer or IComparable it will let you know. You have the ability to create a custom
class that compares objects in different ways (which makes it easy to come up with
different ways of sorting, ex. ascending, descending) and have generic code which
will work in most cases. 
<p></p><h3>Conclusion
</h3><p>
The scenario I described above plays out throughout the .NET framework. Fundamental
things like garbage collection are handled via the IDisposable interface, iterating
over a collection (think foreach) is handled by IEnumerable, comparing objects (like
we described above) is handled by IComparer and IComparable. Interfaces are used extensively.
Hopefully you've gotten a feel for why they're needed and how they're used inside
of .NET. 
</p><p><em>Originally published in Universal Thread Magazine, April 2009</em></p><img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=c914191d-95fd-4d88-bcbb-11bb6b89761f" /></body>
      <title>What&amp;rsquo;s an Interface and Why Should I Care?</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,c914191d-95fd-4d88-bcbb-11bb6b89761f.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2010/07/15/WhatrsquosAnInterfaceAndWhyShouldICare.aspx</link>
      <pubDate>Thu, 15 Jul 2010 23:00:42 GMT</pubDate>
      <description>&lt;p&gt;
Interfaces are an integral part of .NET, yet a lot of new .NET developers (especially
those coming from weakly-typed languages, or languages where interfaces aren't supported)
have difficulty in understanding why they're needed and how (and when) they're used.
If you find yourself in that group you're in good company. It's not a difficult concept
but it can be a bit foreign to developers new to them. 
&lt;/p&gt;
&lt;p&gt;
Let's get the textbook definition out of the way, then take a look at what it really
means (and why you should even care). From Wikipedia: 
&lt;/p&gt;
&lt;p&gt;
&amp;quot;Interface generally refers to an abstraction that an entity provides of itself
to the outside. This separates the methods of external communication from internal
operation, and allows it to be internally modified without affecting the way outside
entities interact with it, as well as provide multiple abstractions of itself. It
may also provide a means of translation between entities which do not speak the same
language, such as between a human and a computer.&amp;quot; 
&lt;/p&gt;
&lt;p&gt;
Hmm - OK. While technically correct that doesn't really help, does it? Did your eyes
glaze over like mine did while reading that? Maybe if we back up a bit and look at
what a class is we might be able to make some sense of this. 
&lt;/p&gt;
&lt;h3&gt;The Basics
&lt;/h3&gt;
&lt;p&gt;
A class is a collection of methods, properties, and events. It is assumed that each
of these methods, properties, and events &amp;quot;do something&amp;quot;. At least in most
cases (we're going to ignore the idea of an abstract class for right now). So far,
so good. You can create a new instance of this class and do things with it, pass it
around to other classes as a parameter, etc. In a weakly typed language (also known
as a &amp;quot;dynamic language&amp;quot;) you can pretty much pass any type of class around
without having to worry about the type - as long as your code doesn't try to access
a property or method that object doesn't have, you're good to go. The upside to this
is that it's pretty flexible. The downside to this is that mistakes aren't caught
at compile time - your app. just blows up at runtime (so you'd better test!). Strongly-typed
languages take a different approach: you must define the types that can be passed
as parameters to methods. That's OK as long as there is only one specific type your
method acts on, or the type you're passing in inherits from the base type of the parameter
- it's pretty straightforward. The upside is that mistakes (like trying to access
a property or method that doesn't exist) is caught at compile time. The downside is
that it's not as flexible as a dynamic language. 
&lt;/p&gt;
&lt;p&gt;
So what do I mean by &amp;quot;not as flexible&amp;quot;? On the surface it seems pretty reasonable
that a strongly-typed method only accepts specific types - how else would the compiler
(and you) know that it's safe to access a specific method or property? It doesn't.
It only can accept that specific type of class, or any subclass of that same type. 
&lt;/p&gt;
&lt;p&gt;
Why is it OK to accept a subclass of the type? Well, the compiler can be sure that
the subclass has the same exact properties &amp;amp; methods as its parent (it doesn't
care if you add more of them or override the behavior). 
&lt;/p&gt;
&lt;p&gt;
But what if it doesn't? What if you had a class that wasn't of the correct type necssary
to pass into a method and it didn't inherit from that type either? Let's take a look
at an example of this. I wanted to keep it simple enough to understand, but have it
be a REAL scenario (not some contrived example). Those goals are a bit difficult to
balance so I error'd on the real scenario side of things. Hopefully it'll help you
understand WHY some things are the way they are in the framework in addition to understanding
interfaces. 
&lt;/p&gt;
&lt;h3&gt;A Real Example
&lt;/h3&gt;
&lt;p&gt;
For example, let's suppose we create a collection class that can have a collection
of objects (that are all of the same type) and we want to have a method which can
sort them. You want to write a generic Sort routine on your collection class that
can sort any kind of collection of objects, as long as they're the same type. The
first issue you'd run into is, &amp;quot;How do I generically create some code which can
compare ANY type?&amp;quot; Remember - you have to be able to compare strings, numbers,
date/times, maybe custom types someone may have created, etc. So it's not really possible
to be able to compare ANY type. You could cover the basic types and then require the
user to subclass your collection for any other custom types. It's a bit clunky, but
it would work. 
&lt;/p&gt;
&lt;p&gt;
What if, instead, we decided that we'd have another class responsible for doing the
sorting. We'd provide a default implementation and if you had your own custom types
that needed to be sorted you could pass in your own implementation. That's a bit better.
The developer would still need to subclass from our default implementation (since
we've still got the strongly-typed issues here - again, dynamic languages don't have
this &amp;quot;issue&amp;quot;). We could have the developer pass in their version of the
class which does the comparison into the Sort() method. The passed in class would
have a Compare() method and let's say it takes two parameters of the types of the
same type of object and returns an integer value indicating whether one of the objects
is less than, greater than, or equal to the other. 
&lt;/p&gt;
&lt;p&gt;
Let's take a look at what the code might look like for all of this: 
&lt;/p&gt;
&lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;
&lt;div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 400px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Comparer&lt;/span&gt; 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Compare(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; x, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; y) 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; { 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background: #ffffbf"&gt;// Code
to do comparisons here &lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; } 
&lt;br /&gt;
} 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SampleArrayList&lt;/span&gt; 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Sort() 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; { 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Sort(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Comparer&lt;/span&gt;()); 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Sort(&lt;span style="color: #2b91af"&gt;Comparer&lt;/span&gt; comparer) 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; { 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background: #ffffbf"&gt;// Do
sorting here. Call out to comparer object to do the actual comparison &lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; } 
&lt;br /&gt;
}
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;
&lt;div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #2b91af"&gt;SampleArrayList&lt;/span&gt; list
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SampleArrayList&lt;/span&gt;(); 
&lt;br /&gt;
&lt;span style="background: #ffffbf"&gt;// Add items to the list &lt;/span&gt; 
&lt;br /&gt;
list.Sort(); &lt;span style="background: #ffffbf"&gt;// default implementation &lt;/span&gt; 
&lt;br /&gt;
list.Sort(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SomeComparerSubclass()); &lt;span style="background: #ffffbf"&gt;//
A custom sort &lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;br /&gt;
That looks OK. If I wanted to create my own comparison class all I'd do is subclass
from Comparer and override Compare() with my own implementation. But let's take a
step back and think about this for a bit. If you create a new class and want a method
that can compare one instance of that class to another instance of it, where's the
best place for the code? Doing comparison's is a pretty fundamental capability of
a class - we do it all the time with string's, numbers, datetimes, etc. so clearly
it belongs with the class, right? Your only other alternative would be to put it into
another class that acts as a kind of &amp;quot;helper&amp;quot;. That's effectively what we've
forced on any developers that want to use the sorting capability of our collection
for their own custom classes. They MUST create a helper class to do a comparison or
they'd all have to inherit from our Comparer class (and use it as their base object).
That might not be the end of the world but we're only talking about a single example
- there are a lot of other places where this scenario comes up. 
&lt;br /&gt;
&lt;br /&gt;
OK, having to create another class which only does a comparison for a specific type
isn't all that great. Since it makes more sense to have a comparison handled by the
object being compared, let's say we add a method called CompareTo() to any class when
we want to be able to compare it against another instance. In our Comparer class we'll
call that method and, hey, our comparer class is now a bit more generic right? We
know that in .NET all objects inherit from &amp;quot;System.Object&amp;quot; so having our
Comparer class's Compare() method accept &amp;quot;objects&amp;quot; means we can use it with
ANY type. I don't actually have to create a new class for each and every item I'm
going to compare! But wait - we're STILL going to have the problem with calling the
CompareTo() method on our class in the collection; we're back to having to inherit
from a common base class.
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;
&lt;div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Comparer&lt;/span&gt; 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Compare(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; x, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; y) 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; { 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background: #ffffbf"&gt;// Code
to do comparisons here &lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; x.CompareTo(y.CompareTo()); 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; } 
&lt;br /&gt;
}
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
But now how can we call the CompareTo() method on those objects? How do we even know
if those objects have a CompareTo() method? Since .NET is strongly typed you can't
do this - it won't even compile. The class type &amp;quot;object&amp;quot; doesn't have a
&amp;quot;CompareTo&amp;quot; method. The .NET compiler knows that and it won't let you do
that. 
&lt;br /&gt;
&lt;br /&gt;
This is begining to feel like a circular issue, isn't it? 
&lt;p&gt;
&lt;/p&gt;
&lt;h3&gt;Breaking the Cycle
&lt;/h3&gt;
&lt;p&gt;
OK, now what? Well, you could jump through a lot of hoops and use reflection to make
the method call for you. But it's a lot of work. In a dynamic language (such as Visual
FoxPro) code like that is perfectly valid - I can pass any object type into a method
like that and access any properties or methods and VFP doesn't care. If the object
doesn't have those properties or methods it will just blow up at runtime. I'm a good
developer so I won't pass in something that would blow up. .NET sucks - it makes things
so difficult. 
&lt;/p&gt;
&lt;p&gt;
You're basically stuck at this point - you can't do what you'd like to do in .NET.
If .NET supported the idea of multiple inheritance (where class C could inherit from
Class A and from Class B at the same time), we'd be able to still make this work.
But it doesn't. 
&lt;/p&gt;
&lt;h3&gt;Interfaces to the Rescue
&lt;/h3&gt;
&lt;p&gt;
That's where interfaces come in (finally!). Let's take another stab at a more concrete
definition of an interface: An Interface is a definition of the types of properties,
events, and methods a class needs to implement. It's nothing more than a list of properties,
events, and methods (and the various types associated with them) that a class has
to have. While we can't inherit from multiple classes in .NET, we can inherit from
multiple interfaces. 
&lt;/p&gt;
&lt;p&gt;
Getting back to our example, we could define an interface that consists of a public
method called CompareTo that accepts one parameter of the &amp;quot;System.Object&amp;quot;
type (&amp;quot;object&amp;quot; for short). This method needs to return an integer: Less
than zero means this instance is less than the object passed in, zero means it's equal,
and greater than one means it's greater than the passed in object. 
&lt;/p&gt;
&lt;p&gt;
Here's what it might look like: 
&lt;/p&gt;
&lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;
&lt;div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IComparable&lt;/span&gt; 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; CompareTo(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; obj); 
&lt;br /&gt;
}
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
While we're at it, it seems like we might want to do something similar to our Comparer
class: 
&lt;/p&gt;
&lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;
&lt;div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IComparer&lt;/span&gt; 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Compare(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; x, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; y); 
&lt;br /&gt;
}
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Now all we'd need to do is make sure that any class that we want to compare inherits
from the IComparer interface and then &amp;quot;implements&amp;quot; the specified properties,
methods, and events (PEM). That is, you need to make sure your class has all of the
same PEM's as the interface. Then you use the interface as the parameter type instead.
Since we can inherit multiple interfaces on a given type we have a way of giving our
classes the cameleon-like ability of appearing as exactly the right type to methods,
regardless of what class it really inherits from. We'd do the same thing for any class
which can compare two different classes. 
&lt;br /&gt;
&lt;br /&gt;
So we can rewrite the above code: 
&lt;p&gt;
&lt;/p&gt;
&lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;
&lt;div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Comparer&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IComparer&lt;/span&gt; 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Compare(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; x, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; y) 
&lt;br /&gt;
&amp;#160;&amp;#160; { 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="background: #ffffbf"&gt;// Code here
which compares x to y and returns integer &lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160; } 
&lt;br /&gt;
} 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MyCustomClass&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IComparable&lt;/span&gt; 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; CompareTo(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; obj) 
&lt;br /&gt;
&amp;#160;&amp;#160; { 
&lt;br /&gt;
&amp;#160;&amp;#160; } 
&lt;br /&gt;
&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; CompareTo(&lt;span style="color: #2b91af"&gt;MyCustomClass&lt;/span&gt; obj) 
&lt;br /&gt;
&amp;#160;&amp;#160; { 
&lt;br /&gt;
&amp;#160;&amp;#160; } 
&lt;br /&gt;
}
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;br /&gt;
And we rewrite the Sort() method on our collection class SampleArrayList to accept
objects of type &amp;quot;IComparer&amp;quot; instead of &amp;quot;Comparer&amp;quot;:&amp;#160; 
&lt;br /&gt;
&lt;/p&gt;
&lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;
&lt;div style="padding-bottom: 2px; background-color: #dfdfdf; padding-left: 5px; padding-right: 5px; max-height: 300px; overflow: auto; padding-top: 2px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Sort(&lt;span style="color: #2b91af"&gt;IComparer&lt;/span&gt; comparer) 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;#160;&amp;#160; &lt;span style="background: #ffffbf"&gt;// Code here that iterates over the
collection and class Compare() &lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160; &lt;span style="background: #ffffbf"&gt;// with two of the items in our internal
list. &lt;/span&gt; 
&lt;br /&gt;
&lt;span style="background: #ffffbf"&gt;}&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Suddenly all of this starts working again - you get compiler-time checking to make
sure things don't blow up, Intellisense works, etc. In fact the compiler verifies
that you have, in fact, done all of this correctly - if your classes don't implement
IComparer or IComparable it will let you know. You have the ability to create a custom
class that compares objects in different ways (which makes it easy to come up with
different ways of sorting, ex. ascending, descending) and have generic code which
will work in most cases. 
&lt;p&gt;
&lt;/p&gt;
&lt;h3&gt;Conclusion
&lt;/h3&gt;
&lt;p&gt;
The scenario I described above plays out throughout the .NET framework. Fundamental
things like garbage collection are handled via the IDisposable interface, iterating
over a collection (think foreach) is handled by IEnumerable, comparing objects (like
we described above) is handled by IComparer and IComparable. Interfaces are used extensively.
Hopefully you've gotten a feel for why they're needed and how they're used inside
of .NET. 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Originally published in Universal Thread Magazine, April 2009&lt;/em&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=c914191d-95fd-4d88-bcbb-11bb6b89761f" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,c914191d-95fd-4d88-bcbb-11bb6b89761f.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=530c4403-249f-48f1-b513-96123e1bcf0b</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,530c4403-249f-48f1-b513-96123e1bcf0b.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,530c4403-249f-48f1-b513-96123e1bcf0b.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=530c4403-249f-48f1-b513-96123e1bcf0b</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
(This is here just as a reminder to myself)
</p>
        <p>
          <strong>To forward calls on Sprint:</strong>
        </p>
        <ul>
          <li>
Dial *72 plus the area code and phone # you want to forward calls to 
</li>
          <li>
Hit the Talk/Call button. 
</li>
          <li>
When you hear the tone, hang up. 
</li>
        </ul>
        <p>
 <strong>To cancel call forwarding:</strong></p>
        <ul>
          <li>
Dial *720 
</li>
          <li>
Hit Talk/Call. 
</li>
          <li>
When you hear the tone, hang up. 
</li>
        </ul>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=530c4403-249f-48f1-b513-96123e1bcf0b" />
      </body>
      <title>Call Forwarding on Sprint</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,530c4403-249f-48f1-b513-96123e1bcf0b.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2010/07/15/CallForwardingOnSprint.aspx</link>
      <pubDate>Thu, 15 Jul 2010 21:55:52 GMT</pubDate>
      <description>&lt;p&gt;
(This is here just as a reminder to myself)
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;To forward calls on Sprint:&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Dial *72 plus the area code and phone # you want to forward calls to 
&lt;/li&gt;
&lt;li&gt;
Hit the Talk/Call button. 
&lt;/li&gt;
&lt;li&gt;
When you hear the tone, hang up. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&amp;#160;&lt;strong&gt;To cancel call forwarding:&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Dial *720 
&lt;/li&gt;
&lt;li&gt;
Hit Talk/Call. 
&lt;/li&gt;
&lt;li&gt;
When you hear the tone, hang up. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=530c4403-249f-48f1-b513-96123e1bcf0b" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,530c4403-249f-48f1-b513-96123e1bcf0b.aspx</comments>
      <category>Cellphones</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=781a324d-b708-40da-b759-235f9f3cc5f7</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,781a324d-b708-40da-b759-235f9f3cc5f7.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,781a324d-b708-40da-b759-235f9f3cc5f7.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=781a324d-b708-40da-b759-235f9f3cc5f7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've been working on a server monitoring Windows service recently - it's meant to
keep an eye on our servers for various types of failures and, if possible, automatically
recover from them. One of the failures our website experiences once in a while has
to do with our forums. I integrated a third party forum package into our site so our
stores have a place to post messages and talk with one another. Occasionally (and
I have yet to reproduce the failure steps) it will fail, complaining that it can't
find some configuration file. The quick fix is to reset IIS; usually I'll just remote
into the server and do an IISRESET from the command prompt. I wanted my service to
keep an eye out for this type of failure and automatically recycle IIS. Long term
I'd love to track down this failure and fix it the proper way but in the meantime
I just want to be able to recover gracefully.
</p>
        <p>
I found the ServiceController class after a bit of digging and wrapped it up into
two static methods I could call to reset IIS. I just had to figure out the name of
the service I needed to refer to. The easiest way I found of finding this was to just
cycle through the services and display their names. You could write a quick console
app. to do this, but I just used <a href="http://www.linqpad.net" target="_blank">LINQPad</a>,
switched it to C# Statements, added a reference to the System.ServiceProcess.dll (hit
F4), then added the namespace System.ServiceProcess and ran the code. 
</p>
        <p>
As an aside: I can't say enough nice things about LINQPad - it makes it so nice to
be able to test out new classes and ideas. Its name would lead you to believe it's
only good for testing LINQ queries, but you can test out almost any .NET code you
want. I spent the whopping $19 to upgrade to the full version, which adds Intellisense
(the free version doesn't include that). I've added LINQPad to my "must have" .NET
toolkit.
</p>
        <p>
          <img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/StartingandStoppingServicesin.NET_12E87/image_3.png" width="826" height="666" />
        </p>
        <p>
You might be wondering what the Dump() method does, since it's not part of the ServiceController
class. LINQPad has a nice extension method named Dump() that makes it trivial to dump
out the response from almost anything. My sample doesn't show it, but it even handles
nested classes nicely. OK, enough fawning...
</p>
        <p>
I ran this code which made it really easy to find the service names I was interested
in. Once I had them I wrapped up a few of the services I wanted to be able to cycle
in their own methods. I ended up wrapping the Start/Stop calls in a try/catch; it
would throw an exception if I tried starting a service which was already running or
stopping a service which had already stopped. 
</p>
        <div style="font-family: consolas, courier new; background: white; color: black; font-size: 10pt">
          <p style="margin: 0px">
            <span style="color: blue">private</span>
            <span style="color: blue">void</span> ResetIIS()
</p>
          <p style="margin: 0px">
{
</p>
          <p style="margin: 0px">
    StopService(<span style="background: #e5e5e5">"W3SVC"</span>, 10);
</p>
          <p style="margin: 0px">
    StartService(<span style="background: #e5e5e5">"W3SVC"</span>,
15);
</p>
          <p style="margin: 0px">
}
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
            <span style="color: blue">private</span>
            <span style="color: blue">void</span> ResetStateServer()
</p>
          <p style="margin: 0px">
{
</p>
          <p style="margin: 0px">
    StopService(<span style="background: #e5e5e5">"aspnet_state"</span>,
15);
</p>
          <p style="margin: 0px">
    StartService(<span style="background: #e5e5e5">"aspnet_state"</span>,
15);
</p>
          <p style="margin: 0px">
}
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
            <span style="color: blue">public</span>
            <span style="color: blue">static</span>
            <span style="color: blue">void</span> StopService(<span style="color: blue">string</span> serviceName, <span style="color: blue">int</span> timeoutSeconds)
</p>
          <p style="margin: 0px">
{
</p>
          <p style="margin: 0px">
    <span style="color: blue">using</span> (<span style="color: #2b91af">ServiceController</span> controller
= <span style="color: blue">new</span><span style="color: #2b91af">ServiceController</span>(serviceName))
</p>
          <p style="margin: 0px">
    {
</p>
          <p style="margin: 0px">
        <span style="color: blue">try</span></p>
          <p style="margin: 0px">
        {
</p>
          <p style="margin: 0px">
            controller.Stop();
</p>
          <p style="margin: 0px">
            controller.WaitForStatus(<span style="color: #2b91af">ServiceControllerStatus</span>.Stopped, <span style="color: #2b91af">TimeSpan</span>.FromSeconds(timeoutSeconds));
</p>
          <p style="margin: 0px">
        }
</p>
          <p style="margin: 0px">
        <span style="color: blue">catch</span> (<span style="color: #2b91af">InvalidOperationException</span> ex)
</p>
          <p style="margin: 0px">
        {
</p>
          <p style="margin: 0px">
            <span style="background: #ffffbf">//
Service may already be stopped</span></p>
          <p style="margin: 0px">
        }
</p>
          <p style="margin: 0px">
    }            
</p>
          <p style="margin: 0px">
}
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
            <span style="color: blue">public</span>
            <span style="color: blue">static</span>
            <span style="color: blue">void</span> StartService(<span style="color: blue">string</span> serviceName, <span style="color: blue">int</span> timeoutSeconds)
</p>
          <p style="margin: 0px">
{
</p>
          <p style="margin: 0px">
    <span style="color: blue">using</span> (<span style="color: #2b91af">ServiceController</span> controller
= <span style="color: blue">new</span><span style="color: #2b91af">ServiceController</span>(serviceName))
</p>
          <p style="margin: 0px">
    {
</p>
          <p style="margin: 0px">
        <span style="color: blue">try</span></p>
          <p style="margin: 0px">
        {
</p>
          <p style="margin: 0px">
            controller.Start();
</p>
          <p style="margin: 0px">
            controller.WaitForStatus(<span style="color: #2b91af">ServiceControllerStatus</span>.Running, <span style="color: #2b91af">TimeSpan</span>.FromSeconds(timeoutSeconds));
</p>
          <p style="margin: 0px">
        }
</p>
          <p style="margin: 0px">
        <span style="color: blue">catch</span> (<span style="color: #2b91af">InvalidOperationException</span> ex)
</p>
          <p style="margin: 0px">
        {
</p>
          <p style="margin: 0px">
            <span style="background: #ffffbf">//
Service may already be running</span></p>
          <p style="margin: 0px">
        }    
</p>
          <p style="margin: 0px">
    }            
</p>
          <p style="margin: 0px">
}
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
            <span style="color: blue">private</span>
            <span style="color: blue">void</span> ListServices()
</p>
          <p style="margin: 0px">
{
</p>
          <p style="margin: 0px">
    <span style="color: #2b91af">ServiceController</span>[] services
= <span style="color: #2b91af">ServiceController</span>.GetServices();
</p>
          <p style="margin: 0px">
    <span style="color: blue">foreach</span> (<span style="color: #2b91af">ServiceController</span> service <span style="color: blue">in</span> services)
</p>
          <p style="margin: 0px">
    {
</p>
          <p style="margin: 0px">
        <span style="color: blue">string</span> name
= service.DisplayName + <span style="background: #e5e5e5">" : "</span> + service.ServiceName;
</p>
          <p style="margin: 0px">
        <span style="color: #2b91af">Console</span>.WriteLine(name);
</p>
          <p style="margin: 0px">
        <span style="background: #ffffbf">//name.Dump();</span></p>
          <p style="margin: 0px">
    }
</p>
          <p style="margin: 0px">
}
</p>
        </div>
        <p>
          <br />
          <b>Links:</b>
        </p>
        <p>
          <a href="http://www.linqpad.net">http://www.linqpad.net</a>
        </p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=781a324d-b708-40da-b759-235f9f3cc5f7" />
      </body>
      <title>Starting and Stopping Services in .NET</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,781a324d-b708-40da-b759-235f9f3cc5f7.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2009/07/26/StartingAndStoppingServicesInNET.aspx</link>
      <pubDate>Sun, 26 Jul 2009 01:30:50 GMT</pubDate>
      <description>&lt;p&gt;
I've been working on a server monitoring Windows service recently - it's meant to
keep an eye on our servers for various types of failures and, if possible, automatically
recover from them. One of the failures our website experiences once in a while has
to do with our forums. I integrated a third party forum package into our site so our
stores have a place to post messages and talk with one another. Occasionally (and
I have yet to reproduce the failure steps) it will fail, complaining that it can't
find some configuration file. The quick fix is to reset IIS; usually I'll just remote
into the server and do an IISRESET from the command prompt. I wanted my service to
keep an eye out for this type of failure and automatically recycle IIS. Long term
I'd love to track down this failure and fix it the proper way but in the meantime
I just want to be able to recover gracefully.
&lt;/p&gt;
&lt;p&gt;
I found the ServiceController class after a bit of digging and wrapped it up into
two static methods I could call to reset IIS. I just had to figure out the name of
the service I needed to refer to. The easiest way I found of finding this was to just
cycle through the services and display their names. You could write a quick console
app. to do this, but I just used &lt;a href="http://www.linqpad.net" target="_blank"&gt;LINQPad&lt;/a&gt;,
switched it to C# Statements, added a reference to the System.ServiceProcess.dll (hit
F4), then added the namespace System.ServiceProcess and ran the code. 
&lt;/p&gt;
&lt;p&gt;
As an aside: I can't say enough nice things about LINQPad - it makes it so nice to
be able to test out new classes and ideas. Its name would lead you to believe it's
only good for testing LINQ queries, but you can test out almost any .NET code you
want. I spent the whopping $19 to upgrade to the full version, which adds Intellisense
(the free version doesn't include that). I've added LINQPad to my "must have" .NET
toolkit.
&lt;/p&gt;
&lt;p&gt;
&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/StartingandStoppingServicesin.NET_12E87/image_3.png" width="826" height="666"&gt; 
&lt;/p&gt;
&lt;p&gt;
You might be wondering what the Dump() method does, since it's not part of the ServiceController
class. LINQPad has a nice extension method named Dump() that makes it trivial to dump
out the response from almost anything. My sample doesn't show it, but it even handles
nested classes nicely. OK, enough fawning...
&lt;/p&gt;
&lt;p&gt;
I ran this code which made it really easy to find the service names I was interested
in. Once I had them I wrapped up a few of the services I wanted to be able to cycle
in their own methods. I ended up wrapping the Start/Stop calls in a try/catch; it
would throw an exception if I tried starting a service which was already running or
stopping a service which had already stopped. 
&lt;/p&gt;
&lt;div style="font-family: consolas, courier new; background: white; color: black; font-size: 10pt"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; ResetIIS()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; StopService(&lt;span style="background: #e5e5e5"&gt;"W3SVC"&lt;/span&gt;, 10);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; StartService(&lt;span style="background: #e5e5e5"&gt;"W3SVC"&lt;/span&gt;,
15);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; ResetStateServer()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; StopService(&lt;span style="background: #e5e5e5"&gt;"aspnet_state"&lt;/span&gt;,
15);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; StartService(&lt;span style="background: #e5e5e5"&gt;"aspnet_state"&lt;/span&gt;,
15);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; StopService(&lt;span style="color: blue"&gt;string&lt;/span&gt; serviceName, &lt;span style="color: blue"&gt;int&lt;/span&gt; timeoutSeconds)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;ServiceController&lt;/span&gt; controller
= &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ServiceController&lt;/span&gt;(serviceName))
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;try&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controller.Stop();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controller.WaitForStatus(&lt;span style="color: #2b91af"&gt;ServiceControllerStatus&lt;/span&gt;.Stopped, &lt;span style="color: #2b91af"&gt;TimeSpan&lt;/span&gt;.FromSeconds(timeoutSeconds));
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;catch&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;InvalidOperationException&lt;/span&gt; ex)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
Service may already be stopped&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; StartService(&lt;span style="color: blue"&gt;string&lt;/span&gt; serviceName, &lt;span style="color: blue"&gt;int&lt;/span&gt; timeoutSeconds)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;ServiceController&lt;/span&gt; controller
= &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ServiceController&lt;/span&gt;(serviceName))
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;try&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controller.Start();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controller.WaitForStatus(&lt;span style="color: #2b91af"&gt;ServiceControllerStatus&lt;/span&gt;.Running, &lt;span style="color: #2b91af"&gt;TimeSpan&lt;/span&gt;.FromSeconds(timeoutSeconds));
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;catch&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;InvalidOperationException&lt;/span&gt; ex)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
Service may already be running&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; ListServices()
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;ServiceController&lt;/span&gt;[] services
= &lt;span style="color: #2b91af"&gt;ServiceController&lt;/span&gt;.GetServices();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;ServiceController&lt;/span&gt; service &lt;span style="color: blue"&gt;in&lt;/span&gt; services)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; name
= service.DisplayName + &lt;span style="background: #e5e5e5"&gt;" : "&lt;/span&gt; + service.ServiceName;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(name);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//name.Dump();&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;br&gt;
&lt;b&gt;Links:&lt;/b&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.linqpad.net"&gt;http://www.linqpad.net&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=781a324d-b708-40da-b759-235f9f3cc5f7" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,781a324d-b708-40da-b759-235f9f3cc5f7.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=8a7554bd-4a70-4486-a44e-71c472b21a85</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,8a7554bd-4a70-4486-a44e-71c472b21a85.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,8a7554bd-4a70-4486-a44e-71c472b21a85.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=8a7554bd-4a70-4486-a44e-71c472b21a85</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Last year (two years maybe? Time flies...) I built a web-based "e-mail" system that
provided internal-only e-mail on our web portal. That might seem a bit weird, but
we needed a system where we could be sure when an e-mail was sent, to who, when it
was read, ability to recall a message, control who can send messages to who, etc.
Basically we needed to control the content end-to-end. Unfortunately standard e-mail
doesn't give you that level of control, so hence the need for building it. 
</p>
        <p>
I wanted the e-mail to function very similar to Outlook to minimize the learning curve
and help adoption (the old system another provider was hosting was really clunky).
It uses a lot of AJAX technology and had what I thought was a fair amount of the standard
e-mail features: You can create custom folders, move messages, forward messages, reply
to messages, add attachments, it automatically refreshes the e-mail list periodically,
you can view who has read your e-mail (and when), group messages by date or sender,
sort messages, resize the windows, double-click on a message to view it in a larger
window, plus a lot of other smaller features. 
</p>
        <p>
 <img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="WebEmail" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/ManagingUserExpectations_1272B/WebEmail_6.png" width="897" height="520" /></p>
        <p>
          <img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Web Email Move Folder" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/ManagingUserExpectations_1272B/WebEmailMoveFolder_3.png" width="472" height="350" />
        </p>
        <p>
          <img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Web Email New Message" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/ManagingUserExpectations_1272B/WebEmailNewMsg_3.png" width="859" height="673" />
        </p>
        <p>
I thought it turned out nicely but an interesting thing happened; Some users were
unhappy with the level of functionality provided: you couldn't flag messages, drag
and drop a message from the inbox into a folder, the e-mail list didn't have intellisense,
etc. 
</p>
        <p>
Wow - I totally wasn't expecting that reaction (mind you, it was from a fairly small
minority, but it was interesting getting that feedback). 
</p>
        <p>
Of course it doesn't compare to the functionality of Outlook, I thought! They had
100+ developers and a few years of development time. I had, well, me and a few months
(and not just on this particular module)! 
</p>
        <p>
I didn't know what to make of it. I had spent a lot of time adding features, polishing
the UI so it wasn't clunky looking, etc. and they weren't happy with the functionality?
Where did I go wrong? It didn't occur to me until later that, by mirroring the look
and feel of Outlook that I was setting my web-based e-mail client to be compared directly
against Outlook. They weren't comparing it to the clunky old system at all. I had
inadvertently set their expectations much higher than I could deliver because of this.
Ouch. 
</p>
        <p>
In retrospect, I might have been better off delivering a system which functioned and
looked better than the existing system but didn't attempt to look and/or operate like
Outlook at all. For example, if I was able to do this over I'd probably drop the folders
option and simplify the e-mail list to just a nice looking grid list w/sorting (removing
the grouping altogether) and reduced some of the AJAX functionality (ex. when you
click on a message the e-mail icon "opens" and changes from bold text to normal text),
among other things. I would have spent less time on it and had less chance for bugs
to boot. 
</p>
        <p>
I know all about setting a customer's expectations so that there aren't any surprises,
but I completely forgot about some of the implicit expectations that can arise in
a project (and managing those as well). 
</p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=8a7554bd-4a70-4486-a44e-71c472b21a85" />
      </body>
      <title>Managing User Expectations</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,8a7554bd-4a70-4486-a44e-71c472b21a85.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2009/07/26/ManagingUserExpectations.aspx</link>
      <pubDate>Sun, 26 Jul 2009 01:00:16 GMT</pubDate>
      <description>&lt;p&gt;
Last year (two years maybe? Time flies...) I built a web-based "e-mail" system that
provided internal-only e-mail on our web portal. That might seem a bit weird, but
we needed a system where we could be sure when an e-mail was sent, to who, when it
was read, ability to recall a message, control who can send messages to who, etc.
Basically we needed to control the content end-to-end. Unfortunately standard e-mail
doesn't give you that level of control, so hence the need for building it. 
&lt;p&gt;
I wanted the e-mail to function very similar to Outlook to minimize the learning curve
and help adoption (the old system another provider was hosting was really clunky).
It uses a lot of AJAX technology and had what I thought was a fair amount of the standard
e-mail features: You can create custom folders, move messages, forward messages, reply
to messages, add attachments, it automatically refreshes the e-mail list periodically,
you can view who has read your e-mail (and when), group messages by date or sender,
sort messages, resize the windows, double-click on a message to view it in a larger
window, plus a lot of other smaller features. 
&lt;p&gt;
&amp;nbsp;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="WebEmail" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/ManagingUserExpectations_1272B/WebEmail_6.png" width="897" height="520"&gt; 
&lt;p&gt;
&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Web Email Move Folder" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/ManagingUserExpectations_1272B/WebEmailMoveFolder_3.png" width="472" height="350"&gt; 
&lt;p&gt;
&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Web Email New Message" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/ManagingUserExpectations_1272B/WebEmailNewMsg_3.png" width="859" height="673"&gt; 
&lt;p&gt;
I thought it turned out nicely but an interesting thing happened; Some users were
unhappy with the level of functionality provided: you couldn't flag messages, drag
and drop a message from the inbox into a folder, the e-mail list didn't have intellisense,
etc. 
&lt;p&gt;
Wow - I totally wasn't expecting that reaction (mind you, it was from a fairly small
minority, but it was interesting getting that feedback). 
&lt;p&gt;
Of course it doesn't compare to the functionality of Outlook, I thought! They had
100+ developers and a few years of development time. I had, well, me and a few months
(and not just on this particular module)! 
&lt;p&gt;
I didn't know what to make of it. I had spent a lot of time adding features, polishing
the UI so it wasn't clunky looking, etc. and they weren't happy with the functionality?
Where did I go wrong? It didn't occur to me until later that, by mirroring the look
and feel of Outlook that I was setting my web-based e-mail client to be compared directly
against Outlook. They weren't comparing it to the clunky old system at all. I had
inadvertently set their expectations much higher than I could deliver because of this.
Ouch. 
&lt;p&gt;
In retrospect, I might have been better off delivering a system which functioned and
looked better than the existing system but didn't attempt to look and/or operate like
Outlook at all. For example, if I was able to do this over I'd probably drop the folders
option and simplify the e-mail list to just a nice looking grid list w/sorting (removing
the grouping altogether) and reduced some of the AJAX functionality (ex. when you
click on a message the e-mail icon "opens" and changes from bold text to normal text),
among other things. I would have spent less time on it and had less chance for bugs
to boot. 
&lt;p&gt;
I know all about setting a customer's expectations so that there aren't any surprises,
but I completely forgot about some of the implicit expectations that can arise in
a project (and managing those as well). 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=8a7554bd-4a70-4486-a44e-71c472b21a85" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,8a7554bd-4a70-4486-a44e-71c472b21a85.aspx</comments>
      <category>Software Development</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=d60c48c6-ad06-4e0b-8dcc-727a2053e480</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,d60c48c6-ad06-4e0b-8dcc-727a2053e480.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,d60c48c6-ad06-4e0b-8dcc-727a2053e480.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d60c48c6-ad06-4e0b-8dcc-727a2053e480</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It looks like I'll be speaking at this year's Southwest Fox 2009. I'll be presenting
two different topics: 
</p>
        <p>
          <a href="http://www.swfox.net/sessions.aspx#Full_Text_Search_using_Lucene.NET" target="_blank">Full
Text Search using Lucene.NET</a> and 
<br /><a href="http://www.swfox.net/sessions.aspx#Refactoring_Legacy_Code" target="_blank">Refactoring
Legacy Code.</a></p>
        <p>
        </p>
        <p>
I'm looking forward to catching Craig Boyd's <a href="http://www.swfox.net/sessions.aspx#FLLs_and_the_Visual_FoxPro_API" target="_blank">FLLs
and the Visual FoxPro API</a> session (assuming the schedule allows it). I had debated
whether to interface to Lucene.NET from an FLL, but ultimately decided that it didn't
quite fit with the way I imagined it being used. Craig has a number of different FLL's
over on his <a href="http://www.sweetpotatosoftware.com/" target="_blank">site</a>,
so if you've ever wondered how to put together an FLL this should be good. 
</p>
        <p>
Christof Wollenhaupt's session, <a href="http://www.swfox.net/sessions.aspx#Using_.NET_in_FoxPro_Applications" target="_blank">Using
.NET in FoxPro Applications</a> should also be a nice companion to my Lucene session.
I hadn't planned on covering too much of the interop story in my session, I'll be
focusing more on actual use. This should give you a bit more background if you're
interested.
</p>
        <p>
Refactoring is a big topic, so you might want to check out Alan Stevens's <a href="http://www.swfox.net/sessions.aspx#Break_It_Down:_Dealing_With_Legacy_Code" target="_blank">Break
It Down: Dealing With Legacy Code</a> pre-con session. Then check out my session as
a refresher and (hopefully) come away with some other ideas on how to manage legacy
code. If you can't make the pre-con, hopefully you'll still find my session valuable.
I plan on showing real code and some of the ways I have handled refactoring, things
to look out for, and various refactoring techniques.
</p>
        <p>
I look forward to seeing you at <a href="http://www.swfox.net/register.aspx" target="_blank">Southwest
Fox</a>. 
</p>
        <p>
 
</p>
        <p>
          <strong>Links</strong>
        </p>
        <p>
          <a title="http://www.swfox.net/sessions.aspx#Full_Text_Search_using_Lucene.NET" href="http://www.swfox.net/sessions.aspx#Full_Text_Search_using_Lucene.NET">http://www.swfox.net/sessions.aspx#Full_Text_Search_using_Lucene.NET</a>
          <br />
          <a title="http://www.swfox.net/sessions.aspx#Refactoring_Legacy_Code" href="http://www.swfox.net/sessions.aspx#Refactoring_Legacy_Code">http://www.swfox.net/sessions.aspx#Refactoring_Legacy_Code</a>
          <br />
          <a title="http://www.swfox.net/sessions.aspx#FLLs_and_the_Visual_FoxPro_API" href="http://www.swfox.net/sessions.aspx#FLLs_and_the_Visual_FoxPro_API">http://www.swfox.net/sessions.aspx#FLLs_and_the_Visual_FoxPro_API</a>
          <br />
          <a title="http://www.swfox.net/sessions.aspx#Using_.NET_in_FoxPro_Applications" href="http://www.swfox.net/sessions.aspx#Using_.NET_in_FoxPro_Applications">http://www.swfox.net/sessions.aspx#Using_.NET_in_FoxPro_Applications</a>
          <br />
          <a title="http://www.swfox.net/sessions.aspx#Break_It_Down:_Dealing_With_Legacy_Code" href="http://www.swfox.net/sessions.aspx#Break_It_Down:_Dealing_With_Legacy_Code">http://www.swfox.net/sessions.aspx#Break_It_Down:_Dealing_With_Legacy_Code</a>
          <br />
          <a title="http://www.swfox.net/register.aspx" href="http://www.swfox.net/register.aspx">http://www.swfox.net/register.aspx</a>
        </p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=d60c48c6-ad06-4e0b-8dcc-727a2053e480" />
      </body>
      <title>Southwest Fox 2009</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,d60c48c6-ad06-4e0b-8dcc-727a2053e480.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2009/05/03/SouthwestFox2009.aspx</link>
      <pubDate>Sun, 03 May 2009 22:36:28 GMT</pubDate>
      <description>&lt;p&gt;
It looks like I'll be speaking at this year's Southwest Fox 2009. I'll be presenting
two different topics: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.swfox.net/sessions.aspx#Full_Text_Search_using_Lucene.NET" target="_blank"&gt;Full
Text Search using Lucene.NET&lt;/a&gt; and 
&lt;br&gt;
&lt;a href="http://www.swfox.net/sessions.aspx#Refactoring_Legacy_Code" target="_blank"&gt;Refactoring
Legacy Code.&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
I'm looking forward to catching Craig Boyd's &lt;a href="http://www.swfox.net/sessions.aspx#FLLs_and_the_Visual_FoxPro_API" target="_blank"&gt;FLLs
and the Visual FoxPro API&lt;/a&gt; session (assuming the schedule allows it). I had debated
whether to interface to Lucene.NET from an FLL, but ultimately decided that it didn't
quite fit with the way I imagined it being used. Craig has a number of different FLL's
over on his &lt;a href="http://www.sweetpotatosoftware.com/" target="_blank"&gt;site&lt;/a&gt;,
so if you've ever wondered how to put together an FLL this should be good. 
&lt;/p&gt;
&lt;p&gt;
Christof Wollenhaupt's session, &lt;a href="http://www.swfox.net/sessions.aspx#Using_.NET_in_FoxPro_Applications" target="_blank"&gt;Using
.NET in FoxPro Applications&lt;/a&gt; should also be a nice companion to my Lucene session.
I hadn't planned on covering too much of the interop story in my session, I'll be
focusing more on actual use. This should give you a bit more background if you're
interested.
&lt;/p&gt;
&lt;p&gt;
Refactoring is a big topic, so you might want to check out Alan Stevens's &lt;a href="http://www.swfox.net/sessions.aspx#Break_It_Down:_Dealing_With_Legacy_Code" target="_blank"&gt;Break
It Down: Dealing With Legacy Code&lt;/a&gt; pre-con session. Then check out my session as
a refresher and (hopefully) come away with some other ideas on how to manage legacy
code. If you can't make the pre-con, hopefully you'll still find my session valuable.
I plan on showing real code and some of the ways I have handled refactoring, things
to look out for, and various refactoring techniques.
&lt;/p&gt;
&lt;p&gt;
I look forward to seeing you at &lt;a href="http://www.swfox.net/register.aspx" target="_blank"&gt;Southwest
Fox&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Links&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://www.swfox.net/sessions.aspx#Full_Text_Search_using_Lucene.NET" href="http://www.swfox.net/sessions.aspx#Full_Text_Search_using_Lucene.NET"&gt;http://www.swfox.net/sessions.aspx#Full_Text_Search_using_Lucene.NET&lt;/a&gt;
&lt;br&gt;
&lt;a title="http://www.swfox.net/sessions.aspx#Refactoring_Legacy_Code" href="http://www.swfox.net/sessions.aspx#Refactoring_Legacy_Code"&gt;http://www.swfox.net/sessions.aspx#Refactoring_Legacy_Code&lt;/a&gt;
&lt;br&gt;
&lt;a title="http://www.swfox.net/sessions.aspx#FLLs_and_the_Visual_FoxPro_API" href="http://www.swfox.net/sessions.aspx#FLLs_and_the_Visual_FoxPro_API"&gt;http://www.swfox.net/sessions.aspx#FLLs_and_the_Visual_FoxPro_API&lt;/a&gt;
&lt;br&gt;
&lt;a title="http://www.swfox.net/sessions.aspx#Using_.NET_in_FoxPro_Applications" href="http://www.swfox.net/sessions.aspx#Using_.NET_in_FoxPro_Applications"&gt;http://www.swfox.net/sessions.aspx#Using_.NET_in_FoxPro_Applications&lt;/a&gt;
&lt;br&gt;
&lt;a title="http://www.swfox.net/sessions.aspx#Break_It_Down:_Dealing_With_Legacy_Code" href="http://www.swfox.net/sessions.aspx#Break_It_Down:_Dealing_With_Legacy_Code"&gt;http://www.swfox.net/sessions.aspx#Break_It_Down:_Dealing_With_Legacy_Code&lt;/a&gt;
&lt;br&gt;
&lt;a title="http://www.swfox.net/register.aspx" href="http://www.swfox.net/register.aspx"&gt;http://www.swfox.net/register.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=d60c48c6-ad06-4e0b-8dcc-727a2053e480" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,d60c48c6-ad06-4e0b-8dcc-727a2053e480.aspx</comments>
      <category>Conference</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=f0ffb32b-b0e0-434c-895c-71a384f20799</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,f0ffb32b-b0e0-434c-895c-71a384f20799.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,f0ffb32b-b0e0-434c-895c-71a384f20799.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f0ffb32b-b0e0-434c-895c-71a384f20799</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Check out my article in this month's <a href="http://www.universalthread.com/ViewPageMainPage.aspx?Session=37395863654242725751383D204A2F4E456275325279766563597439693271307250673D3D" target="_blank">UT
Magazine (April 2009)</a> about interfaces in .NET. I try to explain the how's and
why's of them, especially when coming from a loosely-typed language (such as VFP).
Hopefully you'll find it useful.
</p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=f0ffb32b-b0e0-434c-895c-71a384f20799" />
      </body>
      <title>What's an Interface?</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,f0ffb32b-b0e0-434c-895c-71a384f20799.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2009/04/21/WhatsAnInterface.aspx</link>
      <pubDate>Tue, 21 Apr 2009 22:38:58 GMT</pubDate>
      <description>&lt;p&gt;
Check out my article in this month's &lt;a href="http://www.universalthread.com/ViewPageMainPage.aspx?Session=37395863654242725751383D204A2F4E456275325279766563597439693271307250673D3D" target="_blank"&gt;UT
Magazine (April 2009)&lt;/a&gt; about interfaces in .NET. I try to explain the how's and
why's of them, especially when coming from a loosely-typed language (such as VFP).
Hopefully you'll find it useful.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=f0ffb32b-b0e0-434c-895c-71a384f20799" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,f0ffb32b-b0e0-434c-895c-71a384f20799.aspx</comments>
      <category>.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=039366e3-976f-400e-9c23-ccbcae3c1254</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,039366e3-976f-400e-9c23-ccbcae3c1254.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,039366e3-976f-400e-9c23-ccbcae3c1254.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=039366e3-976f-400e-9c23-ccbcae3c1254</wfw:commentRss>
      <slash:comments>9</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <style type="text/css">
.code { background-color: #efefef; font-family:consolas,courier new; }
</style>
        <p>
I just <a href="http://www.rcs-solutions.com/downloads.aspx" target="_blank">posted</a> a
new release of my calendar controls that includes a bunch of new functionality, some
more documentation (courtesy of <a href="http://www.west-wind.com/wwHelp/" target="_blank">HTML
Help Builder</a> from West Wind), along with a few more samples of how this is all
supposed to work. 
</p>
        <p>
          <strong>A Bit of History </strong>
        </p>
        <p>
This all initially started with a small calendar. I initially planned on using Microsoft's
ActiveX calendar but realized I needed to be able to select multiple days. Their control
really didn't quite work the way I needed it to, so I created my own. I created three
different sizes (normal, smaller, and smallest) just because it was easy to do (they're
all the same control) and I thought I might need it. Like any project the "hey, wouldn't
it be cool if..." features started to grow. In some cases, I needed this functionality
for an application anyway, so I went ahead and improved them. 
</p>
        <p>
          <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="200" alt="Calendar" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/Calendar_3.png" width="215" border="0" />
        </p>
        <p>
The first thing I ended up needing was a drop-down calendar. I already had the calendar
portion, so all I needed to do was show and hide it when you clicked on a button next
to a text box. So that's basically what I did. It worked well enough, but if the control
happened to be at the bottom of a form it was clipped - the initial control was based
on a container. I moved this into a form and adjusted the code a bit so it would be
able to bleed off the form. 
</p>
        <p>
I needed to be able to bind to a date/time field but only display the date portion
for data coming from SQL Server, so I named it "rcsDatetimePicker". In hindsight,
not a great name. It gives you the impression it lets you view/edit both the date
and time portion when in fact it doesn't. At this point I've got a bunch of code which
depends on it so it's not being renamed (sorry). 
</p>
        <p>
          <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="223" alt="DatePicker" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/DatePicker_3.png" width="218" border="0" />
        </p>
        <p>
A common use-case for dropdown calendars is to pick a date range. I took an idea from
a previous job where you could link two date controls to keep the start date and the
end dates from overlapping (ex. the start date can be after the end date). So this
was added. 
</p>
        <p>
I worked on another project which needed a time control (hours/minutes) so I created
one. It seemed like a natural fit to this calendar library so it's been added in.
The next logical idea is, "hey, I need a date/time dropdown calendar". The better
name for this was already taken, so this was was named rcsCtrDateTimePicker. Yeah,
not great, but I didn't have any other ideas. 
</p>
        <p>
          <a href="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/DateTimePicker_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="228" alt="DateTimePicker" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/DateTimePicker_thumb.png" width="285" border="0" />
          </a>
        </p>
        <p>
Finally, I just worked on an application which needed an Outlook-style calendar (month
view). It seemed like I already had most of the work done from my other calendar,
so (I optimistically though) it wouldn't be a big deal to re-purpose it. It actually
required a number of changes so it could be nicely resized, display events, etc. 
</p>
        <p>
That's basically where the library is today: 3 different sized "static" calendars,
a drop-down date w/calendar, a drop-down date/time w/calendar, a time control, plus
a large resizable calendar that can have events displayed on it. 
</p>
        <p>
          <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="449" alt="LargeCalendar" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/LargeCalendar_3.png" width="501" border="0" />
        </p>
        <p>
          <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="469" alt="LargeCalendarMoreEvents" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/LargeCalendarMoreEvents_3.png" width="551" border="0" />
        </p>
        <p>
I've tried to provide a few more examples of how these controls can be used along
with a help file. It's not as comprehensive as I'd like, but it's a decent start. 
</p>
        <p>
          <strong>Misc. Notes</strong>
        </p>
        <p>
One thing that's not really covered in the help yet is related to performance of the
large calendar when you have a lot of events on it. I ran into this during testing
- as you add more events, the calendar navigation became slower and slower. I attempted
to optimize this a bit but ultimately ended up modifying my application code to only
populate events for the current month plus one month prior and one month following.
The calendar shows days from the previous and following months, so if I didn't populate
them they'd be missing from the calendar. 
</p>
        <p>
You can hook in populating events via the RefreshEvents() event. It fires anytime
the calendar needs to be refreshed. I'd suggest just using BINDEVENT to call a form-level
method for this event: 
</p>
        <div class="code">
          <p>
BINDEVENT(This.ctrCalendar, "RefreshEvents", This, "RefreshEvents")  
</p>
        </div>
        <p>
You can determine the current month by looking at the iCurrentYear/iCurrentMonth properties. 
</p>
        <p>
          <strong>Getting Started</strong>
        </p>
        <p>
I'd suggest playing around with the samples and digging through the help file to get
started. The examples cover most of the basic functionality (try clicking on everything
and hovering over things, resizing, etc.) and the help file explains some of the class
structure. 
</p>
        <p>
Let me know what you think. 
</p>
        <p>
          <strong>Links</strong>
        </p>
        <p>
          <a title="http://www.west-wind.com/wwHelp/" href="http://www.west-wind.com/wwHelp/">http://www.west-wind.com/wwHelp/</a>
          <br />
          <a href="http://www.rcs-solutions.com/downloads.aspx">http://www.rcs-solutions.com/downloads.aspx</a>
        </p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=039366e3-976f-400e-9c23-ccbcae3c1254" />
      </body>
      <title>Updated VFP Calendar Control</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,039366e3-976f-400e-9c23-ccbcae3c1254.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2009/02/21/UpdatedVFPCalendarControl.aspx</link>
      <pubDate>Sat, 21 Feb 2009 22:36:05 GMT</pubDate>
      <description> &lt;style type="text/css"&gt;
.code { background-color: #efefef; font-family:consolas,courier new; }
&lt;/style&gt;
&lt;p&gt;
I just &lt;a href="http://www.rcs-solutions.com/downloads.aspx" target="_blank"&gt;posted&lt;/a&gt; a
new release of my calendar controls that includes a bunch of new functionality, some
more documentation (courtesy of &lt;a href="http://www.west-wind.com/wwHelp/" target="_blank"&gt;HTML
Help Builder&lt;/a&gt; from West Wind), along with a few more samples of how this is all
supposed to work. 
&lt;p&gt;
&lt;strong&gt;A Bit of History &lt;/strong&gt; 
&lt;p&gt;
This all initially started with a small calendar. I initially planned on using Microsoft's
ActiveX calendar but realized I needed to be able to select multiple days. Their control
really didn't quite work the way I needed it to, so I created my own. I created three
different sizes (normal, smaller, and smallest) just because it was easy to do (they're
all the same control) and I thought I might need it. Like any project the "hey, wouldn't
it be cool if..." features started to grow. In some cases, I needed this functionality
for an application anyway, so I went ahead and improved them. 
&lt;p&gt;
&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="200" alt="Calendar" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/Calendar_3.png" width="215" border="0"&gt; 
&lt;p&gt;
The first thing I ended up needing was a drop-down calendar. I already had the calendar
portion, so all I needed to do was show and hide it when you clicked on a button next
to a text box. So that's basically what I did. It worked well enough, but if the control
happened to be at the bottom of a form it was clipped - the initial control was based
on a container. I moved this into a form and adjusted the code a bit so it would be
able to bleed off the form. 
&lt;p&gt;
I needed to be able to bind to a date/time field but only display the date portion
for data coming from SQL Server, so I named it "rcsDatetimePicker". In hindsight,
not a great name. It gives you the impression it lets you view/edit both the date
and time portion when in fact it doesn't. At this point I've got a bunch of code which
depends on it so it's not being renamed (sorry). 
&lt;p&gt;
&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="223" alt="DatePicker" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/DatePicker_3.png" width="218" border="0"&gt; 
&lt;p&gt;
A common use-case for dropdown calendars is to pick a date range. I took an idea from
a previous job where you could link two date controls to keep the start date and the
end dates from overlapping (ex. the start date can be after the end date). So this
was added. 
&lt;p&gt;
I worked on another project which needed a time control (hours/minutes) so I created
one. It seemed like a natural fit to this calendar library so it's been added in.
The next logical idea is, "hey, I need a date/time dropdown calendar". The better
name for this was already taken, so this was was named rcsCtrDateTimePicker. Yeah,
not great, but I didn't have any other ideas. 
&lt;p&gt;
&lt;a href="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/DateTimePicker_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="228" alt="DateTimePicker" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/DateTimePicker_thumb.png" width="285" border="0"&gt;&lt;/a&gt; 
&lt;p&gt;
Finally, I just worked on an application which needed an Outlook-style calendar (month
view). It seemed like I already had most of the work done from my other calendar,
so (I optimistically though) it wouldn't be a big deal to re-purpose it. It actually
required a number of changes so it could be nicely resized, display events, etc. 
&lt;p&gt;
That's basically where the library is today: 3 different sized "static" calendars,
a drop-down date w/calendar, a drop-down date/time w/calendar, a time control, plus
a large resizable calendar that can have events displayed on it. 
&lt;p&gt;
&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="449" alt="LargeCalendar" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/LargeCalendar_3.png" width="501" border="0"&gt; 
&lt;p&gt;
&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="469" alt="LargeCalendarMoreEvents" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/UpdatedVFPCalendarControl_DF33/LargeCalendarMoreEvents_3.png" width="551" border="0"&gt; 
&lt;p&gt;
I've tried to provide a few more examples of how these controls can be used along
with a help file. It's not as comprehensive as I'd like, but it's a decent start. 
&lt;p&gt;
&lt;strong&gt;Misc. Notes&lt;/strong&gt; 
&lt;p&gt;
One thing that's not really covered in the help yet is related to performance of the
large calendar when you have a lot of events on it. I ran into this during testing
- as you add more events, the calendar navigation became slower and slower. I attempted
to optimize this a bit but ultimately ended up modifying my application code to only
populate events for the current month plus one month prior and one month following.
The calendar shows days from the previous and following months, so if I didn't populate
them they'd be missing from the calendar. 
&lt;p&gt;
You can hook in populating events via the RefreshEvents() event. It fires anytime
the calendar needs to be refreshed. I'd suggest just using BINDEVENT to call a form-level
method for this event: 
&lt;div class="code"&gt;
&lt;p&gt;
BINDEVENT(This.ctrCalendar, "RefreshEvents", This, "RefreshEvents")&amp;nbsp; 
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
You can determine the current month by looking at the iCurrentYear/iCurrentMonth properties. 
&lt;p&gt;
&lt;strong&gt;Getting Started&lt;/strong&gt; 
&lt;p&gt;
I'd suggest playing around with the samples and digging through the help file to get
started. The examples cover most of the basic functionality (try clicking on everything
and hovering over things, resizing, etc.) and the help file explains some of the class
structure. 
&lt;p&gt;
Let me know what you think. 
&lt;p&gt;
&lt;strong&gt;Links&lt;/strong&gt; 
&lt;p&gt;
&lt;a title="http://www.west-wind.com/wwHelp/" href="http://www.west-wind.com/wwHelp/"&gt;http://www.west-wind.com/wwHelp/&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://www.rcs-solutions.com/downloads.aspx"&gt;http://www.rcs-solutions.com/downloads.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=039366e3-976f-400e-9c23-ccbcae3c1254" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,039366e3-976f-400e-9c23-ccbcae3c1254.aspx</comments>
      <category>VFP</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=f3bf9f27-a137-414b-a849-14aa5342b6c2</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,f3bf9f27-a137-414b-a849-14aa5342b6c2.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,f3bf9f27-a137-414b-a849-14aa5342b6c2.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f3bf9f27-a137-414b-a849-14aa5342b6c2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I just uploaded an <a href="http://www.rcs-solutions.com/downloads.aspx" target="_blank">update</a> for
the collapsing comments plug-in for CodeRush/Refactor! I noticed after updating to
the latest version (3.2.3) that it suddenly stopped working. After a bunch of digging,
and going back and forth with <a href="http://twitter.com/rorybecker" target="_blank">Rory
Becker</a> on twitter. He suggested I take a look at manually loading the plug-in
via the new Plug-in Manager (DevExpress &gt; Options &gt; Core &gt; Plug-in Manager).
I noticed that my plug-in (which is written as a refactoring) had it's Load Type set
as "Demand", but most of the other ones were set as "Idle". After a bit of digging
I figured out how to change this in my code - it's an attribute in AssemblyInfo. Making
this change and recompiling seemed to fix the issue.
</p>
        <p>
 
</p>
        <p>
          <strong>Links:</strong>
        </p>
        <p>
          <a title="http://www.rcs-solutions.com/downloads.aspx" href="http://www.rcs-solutions.com/downloads.aspx">http://www.rcs-solutions.com/downloads.aspx</a>
          <br />
          <a href="http://twitter.com/rorybecker">http://twitter.com/rorybecker</a>
        </p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=f3bf9f27-a137-414b-a849-14aa5342b6c2" />
      </body>
      <title>Collapsing Comments Update</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,f3bf9f27-a137-414b-a849-14aa5342b6c2.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2009/02/14/CollapsingCommentsUpdate.aspx</link>
      <pubDate>Sat, 14 Feb 2009 17:39:48 GMT</pubDate>
      <description>&lt;p&gt;
I just uploaded an &lt;a href="http://www.rcs-solutions.com/downloads.aspx" target="_blank"&gt;update&lt;/a&gt; for
the collapsing comments plug-in for CodeRush/Refactor! I noticed after updating to
the latest version (3.2.3) that it suddenly stopped working. After a bunch of digging,
and going back and forth with &lt;a href="http://twitter.com/rorybecker" target="_blank"&gt;Rory
Becker&lt;/a&gt; on twitter. He suggested I take a look at manually loading the plug-in
via the new Plug-in Manager (DevExpress &amp;gt; Options &amp;gt; Core &amp;gt; Plug-in Manager).
I noticed that my plug-in (which is written as a refactoring) had it's Load Type set
as "Demand", but most of the other ones were set as "Idle". After a bit of digging
I figured out how to change this in my code - it's an attribute in AssemblyInfo. Making
this change and recompiling seemed to fix the issue.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Links:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://www.rcs-solutions.com/downloads.aspx" href="http://www.rcs-solutions.com/downloads.aspx"&gt;http://www.rcs-solutions.com/downloads.aspx&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://twitter.com/rorybecker"&gt;http://twitter.com/rorybecker&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=f3bf9f27-a137-414b-a849-14aa5342b6c2" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,f3bf9f27-a137-414b-a849-14aa5342b6c2.aspx</comments>
      <category>CodeRush</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=0a4cbbbe-dd11-4aac-92fc-fecdabab49b6</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,0a4cbbbe-dd11-4aac-92fc-fecdabab49b6.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,0a4cbbbe-dd11-4aac-92fc-fecdabab49b6.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0a4cbbbe-dd11-4aac-92fc-fecdabab49b6</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <style type="text/css">
.code { background-color: #efefef; font-family:consolas,courier new; }
</style>
        <p>
I just finished up a report which generates a list of customers whose birthdays fall
within a specified date range. I wrote a simple query which did essentially:
</p>
        <p>
          <br />
        </p>
        <div class="code">DECLARE @startDate datetime<br />
DECLARE @endDate datetime<br />
SET @startDate = '2009-2-15'<br />
SET @endDate = '2009-3-14'<br /><br />
SELECT c.iid,<br />
        c.FirstName,<br />
        c.LastName,<br />
        c.BirthDate,<br />
        c.Address1,<br />
        c.Address2,<br />
        c.City,<br />
        c.State,<br />
        c.ZipCode<br />
   FROM Customers c<br />
  WHERE c.BirthDate BETWEEN @startDate AND @endDate
</div>
        <p>
        </p>
        <p>
          <br />
Of course, that didn't work. That is, unless our customers happened to actually just
been born (as of when I wrote this they wouldn't have been even born yet). Hmm....My
first thought was maybe joining this to a date table to get the month and day split
apart but that idea falls apart pretty quickly so I dismissed it. I'll come back to
this idea in a second. 
</p>
        <p>
The other simple way to do this is to convert the date to a day of the year, so January
1st is 1, Jan. 2nd is 2, December 31st is 365. SQL Server includes a nice DATEPART()
function to make this easy - you can specify that you want the day of the year with
it. 
</p>
        <p>
So my query was rewritten as: 
</p>
        <p>
        </p>
        <div class="code">
SELECT c.iid,<br />
        c.FirstName,<br />
        c.LastName,<br />
        c.BirthDate,<br />
        c.Address1,<br />
        c.Address2,<br />
        c.City,<br />
        c.State,<br />
        c.ZipCode<br />
   FROM Customers c<br />
  WHERE DATEPART(dayofyear, c.BirthDate) 
<br />
BETWEEN DATEPART(dayofyear, @startDate) AND DATEPART(dayofyear, @endDate)
</div>
        <p>
        </p>
        <p>
          <br />
While this one works it's a bit slow. That's not so surprising since it has to use
DATEPART on the rows to generate the day of the year in the WHERE clause. My actual
code filters the customers a bit more but it was still a fair number of records. Ultimately,
since this a summary/reporting table that gets populated and updated nightly I just
added another (integer) column to store the precalculated day of the year number. 
</p>
        <p>
Surprisingly, this version isn't that much faster - maybe 15% or so. Apparently DATEPART
is pretty quick. 
</p>
        <p>
It wasn't until after making these changes that I realized I could have added a day
of the year column to my date table, done a join then used this column in my WHERE
clause. That actually would have been easier if it had occurred to me sooner. I'm
guessing performance is probably equivalent, especially since adding the column directly
in the table didn't have a huge impact on the speed of the query.
</p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=0a4cbbbe-dd11-4aac-92fc-fecdabab49b6" />
      </body>
      <title>Query for Birthdays</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,0a4cbbbe-dd11-4aac-92fc-fecdabab49b6.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2009/02/07/QueryForBirthdays.aspx</link>
      <pubDate>Sat, 07 Feb 2009 20:22:48 GMT</pubDate>
      <description> &lt;style type="text/css"&gt;
.code { background-color: #efefef; font-family:consolas,courier new; }
&lt;/style&gt;
&lt;p&gt;
I just finished up a report which generates a list of customers whose birthdays fall
within a specified date range. I wrote a simple query which did essentially:
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;div class="code"&gt;DECLARE @startDate datetime&lt;br&gt;
DECLARE @endDate datetime&lt;br&gt;
SET @startDate = '2009-2-15'&lt;br&gt;
SET @endDate = '2009-3-14'&lt;br&gt;
&lt;br&gt;
SELECT c.iid,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.FirstName,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.LastName,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.BirthDate,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.Address1,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.Address2,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.City,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.State,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.ZipCode&lt;br&gt;
&amp;nbsp;&amp;nbsp; FROM Customers c&lt;br&gt;
&amp;nbsp; WHERE c.BirthDate BETWEEN @startDate AND @endDate
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
Of course, that didn't work. That is, unless our customers happened to actually just
been born (as of when I wrote this they wouldn't have been even born yet). Hmm....My
first thought was maybe joining this to a date table to get the month and day split
apart but that idea falls apart pretty quickly so I dismissed it. I'll come back to
this idea in a second. 
&lt;/p&gt;
&lt;p&gt;
The other simple way to do this is to convert the date to a day of the year, so January
1st is 1, Jan. 2nd is 2, December 31st is 365. SQL Server includes a nice DATEPART()
function to make this easy - you can specify that you want the day of the year with
it. 
&lt;p&gt;
So my query was rewritten as: 
&lt;p&gt;
&lt;div class="code"&gt;
SELECT c.iid,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.FirstName,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.LastName,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.BirthDate,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.Address1,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.Address2,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.City,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.State,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.ZipCode&lt;br&gt;
&amp;nbsp;&amp;nbsp; FROM Customers c&lt;br&gt;
&amp;nbsp; WHERE DATEPART(dayofyear, c.BirthDate) 
&lt;br&gt;
BETWEEN DATEPART(dayofyear, @startDate) AND DATEPART(dayofyear, @endDate)
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
While this one works it's a bit slow. That's not so surprising since it has to use
DATEPART on the rows to generate the day of the year in the WHERE clause. My actual
code filters the customers a bit more but it was still a fair number of records. Ultimately,
since this a summary/reporting table that gets populated and updated nightly I just
added another (integer) column to store the precalculated day of the year number. 
&lt;/p&gt;
&lt;p&gt;
Surprisingly, this version isn't that much faster - maybe 15% or so. Apparently DATEPART
is pretty quick. 
&lt;/p&gt;
&lt;p&gt;
It wasn't until after making these changes that I realized I could have added a day
of the year column to my date table, done a join then used this column in my WHERE
clause. That actually would have been easier if it had occurred to me sooner. I'm
guessing performance is probably equivalent, especially since adding the column directly
in the table didn't have a huge impact on the speed of the query.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=0a4cbbbe-dd11-4aac-92fc-fecdabab49b6" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,0a4cbbbe-dd11-4aac-92fc-fecdabab49b6.aspx</comments>
      <category>SQL</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=a3630b61-fca5-458f-a0b8-b0c59f856ad2</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,a3630b61-fca5-458f-a0b8-b0c59f856ad2.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,a3630b61-fca5-458f-a0b8-b0c59f856ad2.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=a3630b61-fca5-458f-a0b8-b0c59f856ad2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've been using CR/R! for a while and one of the simplest changes I've made that makes
using it a bit easier is redefining the "Refactor" key - that's the key which causes
the refactoring options to pop-up. I've switched mine to just use ` from its default
of Ctrl+` - one keypress (it's not like I use the dumb key for much of anything else).
There are some many options in CR/R! it's not always easy to find this. 
</p>
        <p>
To set it: 
</p>
        <ul>
          <li>
DevExpress &gt; Options</li>
          <li>
From the side menu select "IDE", then "Shortcuts"</li>
          <li>
In the list you should see "Refactor!", underneath that is the key bound to Refactor.</li>
          <li>
Click on it and on the right hand side change they key binding to whatever you'd like.</li>
          <li>
Hit Apply. 
</li>
        </ul>
        <p>
          <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="547" alt="RefactorKey" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/HowtoChangetheCodeRushRefactorKey_11D4F/RefactorKey_3.png" width="1030" border="0" />
        </p>
        <p>
That all that's needed. 
</p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=a3630b61-fca5-458f-a0b8-b0c59f856ad2" />
      </body>
      <title>How to Change the CodeRush Refactor Key</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,a3630b61-fca5-458f-a0b8-b0c59f856ad2.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2009/01/17/HowToChangeTheCodeRushRefactorKey.aspx</link>
      <pubDate>Sat, 17 Jan 2009 01:17:22 GMT</pubDate>
      <description>&lt;p&gt;
I've been using CR/R! for a while and one of the simplest changes I've made that makes
using it a bit easier is redefining the "Refactor" key - that's the key which causes
the refactoring options to pop-up. I've switched mine to just use ` from its default
of Ctrl+` - one keypress (it's not like I use the dumb key for much of anything else).
There are some many options in CR/R! it's not always easy to find this. 
&lt;p&gt;
To set it: 
&lt;ul&gt;
&lt;li&gt;
DevExpress &amp;gt; Options&lt;/li&gt;
&lt;li&gt;
From the side menu select "IDE", then "Shortcuts"&lt;/li&gt;
&lt;li&gt;
In the list you should see "Refactor!", underneath that is the key bound to Refactor.&lt;/li&gt;
&lt;li&gt;
Click on it and on the right hand side change they key binding to whatever you'd like.&lt;/li&gt;
&lt;li&gt;
Hit Apply. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="547" alt="RefactorKey" src="http://www.rcs-solutions.com/blog/content/binary/WindowsLiveWriter/HowtoChangetheCodeRushRefactorKey_11D4F/RefactorKey_3.png" width="1030" border="0"&gt; 
&lt;/p&gt;
&lt;p&gt;
That all that's needed. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=a3630b61-fca5-458f-a0b8-b0c59f856ad2" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,a3630b61-fca5-458f-a0b8-b0c59f856ad2.aspx</comments>
      <category>CodeRush</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=32a4ffa4-0389-4b6c-94a3-3f637f5cac89</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,32a4ffa4-0389-4b6c-94a3-3f637f5cac89.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,32a4ffa4-0389-4b6c-94a3-3f637f5cac89.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=32a4ffa4-0389-4b6c-94a3-3f637f5cac89</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <style type="text/css">
.code { background-color: #efefef; font-family:consolas,courier new; }
</style>
Extension methods were added as a new compiler feature in .NET 3.5. More specifically,
that means you can use VS 2008 to use an extension method and then use VS's multi-targeting
to run it under .NET 2.0. They're basically a means of tacking on methods onto existing
classes or interfaces w/o actually needed to subclass or modify an interface. It's
used extensively by (and added because of) LINQ. The methods aren't really part of
the class, but the way you use them (and the way they appear in intellisense) make
them feel like they're now part of the class. They're essentially static methods scoped
to a specific interface or class. 
</p>
        <p>
I've been playing around with them a bit and ran into a case where I thought they'd
be kind of a cool fit. I've needed to be able to convert a datatable into a comma-delimited
file (CSV) so it can easily be opening in something like Excel, or pretty much anything
that understands CSV files. I could create a separate class to do this, but it seems
like this should be part of the DataTable class. To write an extension method you
basically create a static method in a static class and prefix the first parameter
with "this". Yep, that's about it. 
</p>
        <p>
I wanted it to basically work like this: 
</p>
        <div class="code">DataTable table = myBizObj.DataSet.Tables["SomeTable"]; 
<br />
string csv = table.ToCSV(); 
</div>
        <p>
Creating the CSV is pretty straightforward - I loop through the column headers to
generate the first header row, then I loop through each row in the table, then each
item in the ItemArray of the row. I specifically decided to use quotes as delimiters
around everything to keep it simple - the rules as to when you can/should include
quotes for a CSV are pretty complicated. The only thing I do is escape out embedded
quotes in the data by doubling them, ex. " becomes "". As soon as I had it working,
I decided to create a few more overloads to let me control whether a header row was
required, and the actual delimiter used (ex. instead of comma you could change it
to a | pipe for example). Their is some example code in the XML help at the top of
the class. In addition, I'm actually using this for a web page so it might be helpful
to see what that code looks like: 
</p>
        <div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new">
          <p style="margin: 0px">
            <span style="color: blue">string</span> results = act.DataSet.Tables[tableName].ToCSV();
</p>
          <p style="margin: 0px">
            <span style="color: blue">string</span> mimeType = RCSSolutions.Web.<span style="color: #2b91af">Utility</span>.DetermineMimeType(<span style="background: #e5e5e5">"csv"</span>);
</p>
          <p style="margin: 0px">
Response.ContentType = mimeType;
</p>
          <p style="margin: 0px">
Response.AddHeader(<span style="background: #e5e5e5">"Content-Length"</span>, results.Length.ToString());
</p>
          <p style="margin: 0px">
Response.AddHeader(<span style="background: #e5e5e5">"Content-disposition"</span>,
</p>
          <p style="margin: 0px">
                  
s<span style="color: blue">tring</span>.Format(<span style="background: #e5e5e5">"attachment;filename={0}"</span>, <span style="background: #e5e5e5">"DelimitedList.CSV"</span>));
</p>
          <p style="margin: 0px">
Response.Write(results);
</p>
          <p style="margin: 0px">
Response.End();
</p>
        </div>
        <p>
I'm calling out to another helper class which returns the mime type - in this case,
all it does is return "application/csv". The above code basically pops open a dialog
box with the file name filled in the browser on the client side. 
</p>
        <div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new">
          <p style="margin: 0px">
            <span style="color: blue">using</span> System;
</p>
          <p style="margin: 0px">
            <span style="color: blue">using</span> System.Collections.Generic;
</p>
          <p style="margin: 0px">
            <span style="color: blue">using</span> System.Data;
</p>
          <p style="margin: 0px">
            <span style="color: blue">using</span> System.Linq;
</p>
          <p style="margin: 0px">
            <span style="color: blue">using</span> System.Text;
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
            <span style="color: blue">namespace</span> RCSSolutions.Utility
</p>
          <p style="margin: 0px">
{
</p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;summary&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;para&gt;</span><span style="background: #ffffbf">Various
extension methods.</span><span style="color: gray">&lt;/para&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;/summary&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> Sample
of using ToCSV</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;example&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> DataTable
table = dv.Table;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> //
Assumes table is a DataTable</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> string
result = table.ToCSV(true);</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> System.IO.File.WriteAllText(@"C:\sample.csv",
result);</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> System.Diagnostics.Process
proc = new System.Diagnostics.Process();</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> proc.StartInfo.FileName
= @"C:\sample.csv";</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> proc.StartInfo.UseShellExecute
= true;</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"> proc.Start();</span></p>
          <p style="margin: 0px">
    <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;/example&gt;</span></p>
          <p style="margin: 0px">
    <span style="color: blue">public</span><span style="color: blue">static</span><span style="color: blue">class</span><span style="color: #2b91af">Extensions</span></p>
          <p style="margin: 0px">
    {        
</p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;summary&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"> Converts
the passed in data table to a CSV-style string.       </span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;/summary&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;param
name="table"&gt;</span><span style="background: #ffffbf">Table to convert</span><span style="color: gray">&lt;/param&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;returns&gt;</span><span style="background: #ffffbf">Resulting
CSV-style string</span><span style="color: gray">&lt;/returns&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: blue">public</span><span style="color: blue">static</span><span style="color: blue">string</span> ToCSV(<span style="color: blue">this</span><span style="color: #2b91af">DataTable</span> table)
</p>
          <p style="margin: 0px">
        {
</p>
          <p style="margin: 0px">
            <span style="color: blue">return</span> ToCSV(table, <span style="background: #e5e5e5">","</span>, <span style="color: blue">true</span>);
</p>
          <p style="margin: 0px">
        }
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;summary&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"> Converts
the passed in data table to a CSV-style string.</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;/summary&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;param
name="table"&gt;</span><span style="background: #ffffbf">Table to convert</span><span style="color: gray">&lt;/param&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;param
name="includeHeader"&gt;</span><span style="background: #ffffbf">true - include headers</span><span style="color: gray">&lt;br/&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"> false
- do not include header column</span><span style="color: gray">&lt;/param&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;returns&gt;</span><span style="background: #ffffbf">Resulting
CSV-style string</span><span style="color: gray">&lt;/returns&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: blue">public</span><span style="color: blue">static</span><span style="color: blue">string</span> ToCSV(<span style="color: blue">this</span><span style="color: #2b91af">DataTable</span> table, <span style="color: blue">bool</span> includeHeader)
</p>
          <p style="margin: 0px">
        {
</p>
          <p style="margin: 0px">
            <span style="color: blue">return</span> ToCSV(table, <span style="background: #e5e5e5">","</span>,
includeHeader);
</p>
          <p style="margin: 0px">
        }
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;summary&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"> Converts
the passed in data table to a CSV-style string.</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;/summary&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;param
name="table"&gt;</span><span style="background: #ffffbf">Table to convert</span><span style="color: gray">&lt;/param&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;param
name="delimiter"&gt;</span><span style="background: #ffffbf">Delimiter used to separate
fields</span><span style="color: gray">&lt;/param&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;param
name="includeHeader"&gt;</span><span style="background: #ffffbf">true - include headers</span><span style="color: gray">&lt;br/&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"> false
- do not include header column</span><span style="color: gray">&lt;/param&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: gray">///</span><span style="background: #ffffbf"></span><span style="color: gray">&lt;returns&gt;</span><span style="background: #ffffbf">Resulting
CSV-style string</span><span style="color: gray">&lt;/returns&gt;</span></p>
          <p style="margin: 0px">
        <span style="color: blue">public</span><span style="color: blue">static</span><span style="color: blue">string</span> ToCSV(<span style="color: blue">this</span><span style="color: #2b91af">DataTable</span> table, <span style="color: blue">string</span> delimiter, <span style="color: blue">bool</span> includeHeader)
</p>
          <p style="margin: 0px">
        {
</p>
          <p style="margin: 0px">
            <span style="color: #2b91af">StringBuilder</span> result
= <span style="color: blue">new</span><span style="color: #2b91af">StringBuilder</span>();
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
            <span style="color: blue">if</span> (includeHeader)
</p>
          <p style="margin: 0px">
            {
</p>
          <p style="margin: 0px">
                <span style="color: blue">foreach</span> (<span style="color: #2b91af">DataColumn</span> column <span style="color: blue">in</span> table.Columns)
</p>
          <p style="margin: 0px">
               
{
</p>
          <p style="margin: 0px">
                   
result.Append(column.ColumnName);
</p>
          <p style="margin: 0px">
                   
result.Append(delimiter);
</p>
          <p style="margin: 0px">
               
}
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
               
result.Remove(--result.Length, 0);
</p>
          <p style="margin: 0px">
               
result.Append(<span style="color: #2b91af">Environment</span>.NewLine);
</p>
          <p style="margin: 0px">
            }
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
            <span style="color: blue">foreach</span> (<span style="color: #2b91af">DataRow</span> row <span style="color: blue">in</span> table.Rows)
</p>
          <p style="margin: 0px">
            {
</p>
          <p style="margin: 0px">
                <span style="color: blue">foreach</span> (<span style="color: blue">object</span> item <span style="color: blue">in</span> row.ItemArray)
</p>
          <p style="margin: 0px">
               
{
</p>
          <p style="margin: 0px">
                    <span style="color: blue">if</span> (item <span style="color: blue">is</span> System.<span style="color: #2b91af">DBNull</span>)
</p>
          <p style="margin: 0px">
                       
result.Append(delimiter);
</p>
          <p style="margin: 0px">
                    <span style="color: blue">else</span></p>
          <p style="margin: 0px">
                   
{
</p>
          <p style="margin: 0px">
                        <span style="color: blue">string</span> itemAsString
= item.ToString();
</p>
          <p style="margin: 0px">
                        <span style="background: #ffffbf">//
Double up all embedded double quotes</span></p>
          <p style="margin: 0px">
                       
itemAsString = itemAsString.Replace(<span style="background: #e5e5e5">"\""</span>, <span style="background: #e5e5e5">"\"\""</span>);
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
                        <span style="background: #ffffbf">//
To keep things simple, always delimit with double-quotes</span></p>
          <p style="margin: 0px">
                        <span style="background: #ffffbf">//
so we don't have to determine in which cases they're necessary</span></p>
          <p style="margin: 0px">
                        <span style="background: #ffffbf">//
and which cases they're not.</span></p>
          <p style="margin: 0px">
                       
itemAsString = <span style="background: #e5e5e5">"\""</span> + itemAsString + <span style="background: #e5e5e5">"\""</span>;
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
                       
result.Append(itemAsString + delimiter);
</p>
          <p style="margin: 0px">
                   
}
</p>
          <p style="margin: 0px">
               
}
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
               
result.Remove(--result.Length, 0);
</p>
          <p style="margin: 0px">
               
result.Append(<span style="color: #2b91af">Environment</span>.NewLine);
</p>
          <p style="margin: 0px">
            }
</p>
          <p style="margin: 0px">
 
</p>
          <p style="margin: 0px">
            <span style="color: blue">return</span> result.ToString();
</p>
          <p style="margin: 0px">
        }
</p>
          <p style="margin: 0px">
    }
</p>
          <p style="margin: 0px">
}
</p>
        </div>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=32a4ffa4-0389-4b6c-94a3-3f637f5cac89" />
      </body>
      <title>Convert DataTable to CSV via Extension Method</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,32a4ffa4-0389-4b6c-94a3-3f637f5cac89.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2009/01/15/ConvertDataTableToCSVViaExtensionMethod.aspx</link>
      <pubDate>Thu, 15 Jan 2009 01:57:00 GMT</pubDate>
      <description>&lt;p&gt;
&lt;style type="text/css"&gt;
.code { background-color: #efefef; font-family:consolas,courier new; }
&lt;/style&gt;
Extension methods were added as a new compiler feature in .NET 3.5. More specifically,
that means you can use VS 2008 to use an extension method and then use VS's multi-targeting
to run it under .NET 2.0. They're basically a means of tacking on methods onto existing
classes or interfaces w/o actually needed to subclass or modify an interface. It's
used extensively by (and added because of) LINQ. The methods aren't really part of
the class, but the way you use them (and the way they appear in intellisense) make
them feel like they're now part of the class. They're essentially static methods scoped
to a specific interface or class. 
&lt;/p&gt;
&lt;p&gt;
I've been playing around with them a bit and ran into a case where I thought they'd
be kind of a cool fit. I've needed to be able to convert a datatable into a comma-delimited
file (CSV) so it can easily be opening in something like Excel, or pretty much anything
that understands CSV files. I could create a separate class to do this, but it seems
like this should be part of the DataTable class. To write an extension method you
basically create a static method in a static class and prefix the first parameter
with "this". Yep, that's about it. 
&lt;/p&gt;
&lt;p&gt;
I wanted it to basically work like this: 
&lt;/p&gt;
&lt;div class="code"&gt;DataTable table = myBizObj.DataSet.Tables["SomeTable"]; 
&lt;br&gt;
string csv = table.ToCSV(); 
&lt;/div&gt;
&lt;p&gt;
Creating the CSV is pretty straightforward - I loop through the column headers to
generate the first header row, then I loop through each row in the table, then each
item in the ItemArray of the row. I specifically decided to use quotes as delimiters
around everything to keep it simple - the rules as to when you can/should include
quotes for a CSV are pretty complicated. The only thing I do is escape out embedded
quotes in the data by doubling them, ex. " becomes "". As soon as I had it working,
I decided to create a few more overloads to let me control whether a header row was
required, and the actual delimiter used (ex. instead of comma you could change it
to a | pipe for example). Their is some example code in the XML help at the top of
the class. In addition, I'm actually using this for a web page so it might be helpful
to see what that code looks like: 
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;string&lt;/span&gt; results = act.DataSet.Tables[tableName].ToCSV();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;string&lt;/span&gt; mimeType = RCSSolutions.Web.&lt;span style="color: #2b91af"&gt;Utility&lt;/span&gt;.DetermineMimeType(&lt;span style="background: #e5e5e5"&gt;"csv"&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
Response.ContentType = mimeType;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
Response.AddHeader(&lt;span style="background: #e5e5e5"&gt;"Content-Length"&lt;/span&gt;, results.Length.ToString());
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
Response.AddHeader(&lt;span style="background: #e5e5e5"&gt;"Content-disposition"&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
s&lt;span style="color: blue"&gt;tring&lt;/span&gt;.Format(&lt;span style="background: #e5e5e5"&gt;"attachment;filename={0}"&lt;/span&gt;, &lt;span style="background: #e5e5e5"&gt;"DelimitedList.CSV"&lt;/span&gt;));
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
Response.Write(results);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
Response.End();
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
I'm calling out to another helper class which returns the mime type - in this case,
all it does is return "application/csv". The above code basically pops open a dialog
box with the file name filled in the browser on the client side. 
&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: consolas, courier new"&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;using&lt;/span&gt; System;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Data;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Linq;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Text;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&lt;span style="color: blue"&gt;namespace&lt;/span&gt; RCSSolutions.Utility
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;para&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;Various
extension methods.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/para&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; Sample
of using ToCSV&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;example&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; DataTable
table = dv.Table;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; //
Assumes table is a DataTable&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; string
result = table.ToCSV(true);&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; System.IO.File.WriteAllText(@"C:\sample.csv",
result);&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; System.Diagnostics.Process
proc = new System.Diagnostics.Process();&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; proc.StartInfo.FileName
= @"C:\sample.csv";&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; proc.StartInfo.UseShellExecute
= true;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; proc.Start();&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/example&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Extensions&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; Converts
the passed in data table to a CSV-style string.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;param
name="table"&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;Table to convert&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;Resulting
CSV-style string&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; ToCSV(&lt;span style="color: blue"&gt;this&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DataTable&lt;/span&gt; table)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; ToCSV(table, &lt;span style="background: #e5e5e5"&gt;","&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; Converts
the passed in data table to a CSV-style string.&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;param
name="table"&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;Table to convert&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;param
name="includeHeader"&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;true - include headers&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; false
- do not include header column&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;Resulting
CSV-style string&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; ToCSV(&lt;span style="color: blue"&gt;this&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DataTable&lt;/span&gt; table, &lt;span style="color: blue"&gt;bool&lt;/span&gt; includeHeader)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; ToCSV(table, &lt;span style="background: #e5e5e5"&gt;","&lt;/span&gt;,
includeHeader);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; Converts
the passed in data table to a CSV-style string.&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;param
name="table"&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;Table to convert&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;param
name="delimiter"&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;Delimiter used to separate
fields&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;param
name="includeHeader"&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;true - include headers&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; false
- do not include header column&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="background: #ffffbf"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="background: #ffffbf"&gt;Resulting
CSV-style string&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; ToCSV(&lt;span style="color: blue"&gt;this&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DataTable&lt;/span&gt; table, &lt;span style="color: blue"&gt;string&lt;/span&gt; delimiter, &lt;span style="color: blue"&gt;bool&lt;/span&gt; includeHeader)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt; result
= &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (includeHeader)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;DataColumn&lt;/span&gt; column &lt;span style="color: blue"&gt;in&lt;/span&gt; table.Columns)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
result.Append(column.ColumnName);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
result.Append(delimiter);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
}
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
result.Remove(--result.Length, 0);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
result.Append(&lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.NewLine);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;DataRow&lt;/span&gt; row &lt;span style="color: blue"&gt;in&lt;/span&gt; table.Rows)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue"&gt;object&lt;/span&gt; item &lt;span style="color: blue"&gt;in&lt;/span&gt; row.ItemArray)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (item &lt;span style="color: blue"&gt;is&lt;/span&gt; System.&lt;span style="color: #2b91af"&gt;DBNull&lt;/span&gt;)
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
result.Append(delimiter);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;else&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
{
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; itemAsString
= item.ToString();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
Double up all embedded double quotes&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
itemAsString = itemAsString.Replace(&lt;span style="background: #e5e5e5"&gt;"\""&lt;/span&gt;, &lt;span style="background: #e5e5e5"&gt;"\"\""&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
To keep things simple, always delimit with double-quotes&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
so we don't have to determine in which cases they're necessary&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background: #ffffbf"&gt;//
and which cases they're not.&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
itemAsString = &lt;span style="background: #e5e5e5"&gt;"\""&lt;/span&gt; + itemAsString + &lt;span style="background: #e5e5e5"&gt;"\""&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
result.Append(itemAsString + delimiter);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
}
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
}
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
result.Remove(--result.Length, 0);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
result.Append(&lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.NewLine);
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; result.ToString();
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="margin: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=32a4ffa4-0389-4b6c-94a3-3f637f5cac89" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,32a4ffa4-0389-4b6c-94a3-3f637f5cac89.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
    </item>
    <item>
      <trackback:ping>http://www.rcs-solutions.com/blog/Trackback.aspx?guid=2e821787-88b3-4afc-8080-e91872cd3106</trackback:ping>
      <pingback:server>http://www.rcs-solutions.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.rcs-solutions.com/blog/PermaLink,guid,2e821787-88b3-4afc-8080-e91872cd3106.aspx</pingback:target>
      <dc:creator>Paul Mrozowski</dc:creator>
      <wfw:comment>http://www.rcs-solutions.com/blog/CommentView,guid,2e821787-88b3-4afc-8080-e91872cd3106.aspx</wfw:comment>
      <wfw:commentRss>http://www.rcs-solutions.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=2e821787-88b3-4afc-8080-e91872cd3106</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was trolling <a href="http://digg.com" target="_blank">Digg</a> tonight and ran
across <a href="http://news.cnet.com/8301-13772_3-10125016-52.html?part=rss" target="_blank">this
article</a> about finding rare songs on <a href="http://www.youtube.com" target="_blank">YouTube</a>.
I hadn't really thought about it but I had found some great <a href="http://www.youtube.com/watch?v=M_bvT-DGcWw" target="_blank">Pink
Floyd</a> videos on there a while back. I've had a song (not Pink Floyd) knocking
around in my brain for a while that I was never able to identify; all I could remember
was "suckerpunch". So I typed "suckerpunch song" into the search on YouTube and bang, <a href="http://www.youtube.com/watch?v=plBna98XZNQ" target="_blank">there
it was</a>. Actually, after hearing this again (besides realizing it was from around
1993) was how much this sounded like Nine Inch Nails, <a href="http://www.youtube.com/watch?v=U2LwEQFK3qc" target="_blank">March
of the Pigs</a> (released around the same time). OK, it doesn't quite match up as
well as it did in my head (or as well as <a href="http://www.youtube.com/watch?v=7xNQZHuAQJ8" target="_blank">this</a>),
but whatever. It's got the same sort of feel.
</p>
        <p>
That got me thinking about when I saw Pink Floyd at the Pontiac Silverdome; I was
trying to figure out <a href="http://ourworld.compuserve.com/homepages/PFArchives/tourdate.htm" target="_blank">what
year I went</a>. This, of course, got me thinking about the first concert I ever saw: <a href="http://www.maidenfans.com/imc/index.php?url=tour06_sit/dates06_sit&amp;link=tours&amp;lang=deu" target="_blank">Iron
Maiden at Joe Louis Arena</a>. That led me back to <a href="http://www.youtube.com/watch?v=AUOpUqni0_g" target="_blank">YouTube</a>.
And <a href="http://www.youtube.com/watch?v=e39D8VBQ4sw" target="_blank">Guitar Hero</a>.
</p>
        <p>
The internets is cool. And a huge waste of time. But mostly cool.
</p>
        <p>
          <strong>Links:</strong>
        </p>
        <p>
          <a href="http://digg.com">http://digg.com</a>
          <br />
          <a title="http://news.cnet.com/8301-13772_3-10125016-52.html?part=rss" href="http://news.cnet.com/8301-13772_3-10125016-52.html?part=rss">http://news.cnet.com/8301-13772_3-10125016-52.html?part=rss</a>
          <br />
          <a title="http://www.youtube.com" href="http://www.youtube.com">http://www.youtube.com</a>
          <br />
          <a href="http://www.youtube.com/watch?v=M_bvT-DGcWw" target="_blank">http://www.youtube.com/watch?v=M_bvT-DGcWw</a>
          <br />
          <a title="http://www.youtube.com/watch?v=plBna98XZNQ" href="http://www.youtube.com/watch?v=plBna98XZNQ">http://www.youtube.com/watch?v=plBna98XZNQ</a>
          <br />
          <a href="http://www.youtube.com/watch?v=U2LwEQFK3qc" target="_blank">http://www.youtube.com/watch?v=U2LwEQFK3qc</a>
          <br />
          <a href="http://www.youtube.com/watch?v=7xNQZHuAQJ8" target="_blank">http://www.youtube.com/watch?v=7xNQZHuAQJ8</a>
          <br />
          <a title="http://ourworld.compuserve.com/homepages/PFArchives/tourdate.htm" href="http://ourworld.compuserve.com/homepages/PFArchives/tourdate.htm">http://ourworld.compuserve.com/homepages/PFArchives/tourdate.htm</a>
          <br />
          <a title="http://www.maidenfans.com/imc/index.php?url=tour06_sit/dates06_sit&amp;link=tours&amp;lang=deu" href="http://www.maidenfans.com/imc/index.php?url=tour06_sit/dates06_sit&amp;link=tours&amp;lang=deu">http://www.maidenfans.com/imc/index.php?url=tour06_sit/dates06_sit&amp;link=tours&amp;lang=deu</a>
          <br />
          <a href="http://www.youtube.com/watch?v=AUOpUqni0_g" target="_blank">http://www.youtube.com/watch?v=AUOpUqni0_g</a>
          <br />
          <a href="http://www.youtube.com/watch?v=e39D8VBQ4sw" target="_blank">http://www.youtube.com/watch?v=e39D8VBQ4sw</a>
        </p>
        <p>
          <strong>Bonus Track</strong> (just because this is a great song):
</p>
        <p>
          <a href="http://www.youtube.com/watch?v=k5JkHBC5lDs" target="_blank">http://www.youtube.com/watch?v=k5JkHBC5lDs</a>
        </p>
        <img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=2e821787-88b3-4afc-8080-e91872cd3106" />
      </body>
      <title>Don't Clog the Tubes</title>
      <guid isPermaLink="false">http://www.rcs-solutions.com/blog/PermaLink,guid,2e821787-88b3-4afc-8080-e91872cd3106.aspx</guid>
      <link>http://www.rcs-solutions.com/blog/2008/12/24/DontClogTheTubes.aspx</link>
      <pubDate>Wed, 24 Dec 2008 03:12:17 GMT</pubDate>
      <description>&lt;p&gt;
I was trolling &lt;a href="http://digg.com" target="_blank"&gt;Digg&lt;/a&gt; tonight and ran
across &lt;a href="http://news.cnet.com/8301-13772_3-10125016-52.html?part=rss" target="_blank"&gt;this
article&lt;/a&gt; about finding rare songs on &lt;a href="http://www.youtube.com" target="_blank"&gt;YouTube&lt;/a&gt;.
I hadn't really thought about it but I had found some great &lt;a href="http://www.youtube.com/watch?v=M_bvT-DGcWw" target="_blank"&gt;Pink
Floyd&lt;/a&gt; videos on there a while back. I've had a song (not Pink Floyd) knocking
around in my brain for a while that I was never able to identify; all I could remember
was "suckerpunch". So I typed "suckerpunch song" into the search on YouTube and bang, &lt;a href="http://www.youtube.com/watch?v=plBna98XZNQ" target="_blank"&gt;there
it was&lt;/a&gt;. Actually, after hearing this again (besides realizing it was from around
1993) was how much this sounded like Nine Inch Nails, &lt;a href="http://www.youtube.com/watch?v=U2LwEQFK3qc" target="_blank"&gt;March
of the Pigs&lt;/a&gt; (released around the same time). OK, it doesn't quite match up as
well as it did in my head (or as well as &lt;a href="http://www.youtube.com/watch?v=7xNQZHuAQJ8" target="_blank"&gt;this&lt;/a&gt;),
but whatever. It's got the same sort of feel.
&lt;/p&gt;
&lt;p&gt;
That got me thinking about when I saw Pink Floyd at the Pontiac Silverdome; I was
trying to figure out &lt;a href="http://ourworld.compuserve.com/homepages/PFArchives/tourdate.htm" target="_blank"&gt;what
year I went&lt;/a&gt;. This, of course, got me thinking about the first concert I ever saw: &lt;a href="http://www.maidenfans.com/imc/index.php?url=tour06_sit/dates06_sit&amp;amp;link=tours&amp;amp;lang=deu" target="_blank"&gt;Iron
Maiden at Joe Louis Arena&lt;/a&gt;. That led me back to &lt;a href="http://www.youtube.com/watch?v=AUOpUqni0_g" target="_blank"&gt;YouTube&lt;/a&gt;.
And &lt;a href="http://www.youtube.com/watch?v=e39D8VBQ4sw" target="_blank"&gt;Guitar Hero&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The internets is cool. And a huge waste of time. But mostly cool.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Links:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://digg.com"&gt;http://digg.com&lt;/a&gt;
&lt;br&gt;
&lt;a title="http://news.cnet.com/8301-13772_3-10125016-52.html?part=rss" href="http://news.cnet.com/8301-13772_3-10125016-52.html?part=rss"&gt;http://news.cnet.com/8301-13772_3-10125016-52.html?part=rss&lt;/a&gt;
&lt;br&gt;
&lt;a title="http://www.youtube.com" href="http://www.youtube.com"&gt;http://www.youtube.com&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://www.youtube.com/watch?v=M_bvT-DGcWw" target="_blank"&gt;http://www.youtube.com/watch?v=M_bvT-DGcWw&lt;/a&gt;
&lt;br&gt;
&lt;a title="http://www.youtube.com/watch?v=plBna98XZNQ" href="http://www.youtube.com/watch?v=plBna98XZNQ"&gt;http://www.youtube.com/watch?v=plBna98XZNQ&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://www.youtube.com/watch?v=U2LwEQFK3qc" target="_blank"&gt;http://www.youtube.com/watch?v=U2LwEQFK3qc&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://www.youtube.com/watch?v=7xNQZHuAQJ8" target="_blank"&gt;http://www.youtube.com/watch?v=7xNQZHuAQJ8&lt;/a&gt;
&lt;br&gt;
&lt;a title="http://ourworld.compuserve.com/homepages/PFArchives/tourdate.htm" href="http://ourworld.compuserve.com/homepages/PFArchives/tourdate.htm"&gt;http://ourworld.compuserve.com/homepages/PFArchives/tourdate.htm&lt;/a&gt;
&lt;br&gt;
&lt;a title="http://www.maidenfans.com/imc/index.php?url=tour06_sit/dates06_sit&amp;amp;link=tours&amp;amp;lang=deu" href="http://www.maidenfans.com/imc/index.php?url=tour06_sit/dates06_sit&amp;amp;link=tours&amp;amp;lang=deu"&gt;http://www.maidenfans.com/imc/index.php?url=tour06_sit/dates06_sit&amp;amp;link=tours&amp;amp;lang=deu&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://www.youtube.com/watch?v=AUOpUqni0_g" target="_blank"&gt;http://www.youtube.com/watch?v=AUOpUqni0_g&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://www.youtube.com/watch?v=e39D8VBQ4sw" target="_blank"&gt;http://www.youtube.com/watch?v=e39D8VBQ4sw&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Bonus Track&lt;/strong&gt; (just because this is a great song):
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.youtube.com/watch?v=k5JkHBC5lDs" target="_blank"&gt;http://www.youtube.com/watch?v=k5JkHBC5lDs&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.rcs-solutions.com/blog/aggbug.ashx?id=2e821787-88b3-4afc-8080-e91872cd3106" /&gt;</description>
      <comments>http://www.rcs-solutions.com/blog/CommentView,guid,2e821787-88b3-4afc-8080-e91872cd3106.aspx</comments>
      <category>Other</category>
    </item>
  </channel>
</rss>