<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>DJ's Blog</title><link>http://blogs.vbcity.com/djjeavons/</link><description>David Jeavons' Blog at vbCity</description><managingEditor>David Jeavons</managingEditor><dc:language>en-GB</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>David Jeavons</dc:creator><title>Extension Methods</title><link>http://blogs.vbcity.com/djjeavons/archive/2008/01/21/8956.aspx</link><pubDate>Mon, 21 Jan 2008 20:36:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2008/01/21/8956.aspx</guid><wfw:comment>http://blogs.vbcity.com/djjeavons/comments/8956.aspx</wfw:comment><comments>http://blogs.vbcity.com/djjeavons/archive/2008/01/21/8956.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.vbcity.com/djjeavons/comments/commentRss/8956.aspx</wfw:commentRss><trackback:ping>http://blogs.vbcity.com/djjeavons/services/trackbacks/8956.aspx</trackback:ping><description>&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;I have only just recently had the time to play with the new features available in VS 2008 and one of the first things that I thought I would take a look at were Extension Methods.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;In a nutshell, extension methods allow you to attach a method onto any .NET type and utilise that method as if it was part of the type out of the box. If you consider the String type, there are many methods attached to the String type that allow you to retrieve it's length, convert the string to upper or lower case, determine if it contains a specific value and so on. However, as with most things in life, there is always something missing. For example, it would be nice if we could proper case the string or determine if the string contained a valid value such as an email address. In the past, this type of functionality would be left to a helper class that we as developers would create ourselves.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;However, with the introduction of extension methods, we can now turn our helper class methods into extension methods of the necessary type and use those methods in the same way that we would any method of the native .NET type.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;To create an extension method in VB 9 we must use a Module as all extension methods must be shared, also the method must be decorated with the Extension &lt;EXTENSION()&gt;attribute. So taking the two examples above (proper casing a string and determining if a string is a valid email address format) we might create a module called "StringExtensions" as follows:&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;
&lt;DIV style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;Option&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Strict&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;On&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;Imports&lt;/SPAN&gt; System.Runtime.CompilerServices&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;Namespace&lt;/SPAN&gt; MyExtensions&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt; StringExtensions&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;EXTENSION()&gt; _&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&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;Function&lt;/SPAN&gt; ToProperCase(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; s &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;) &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; titleCase &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; System.Globalization.TextInfo = &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; System.Globalization.CultureInfo(&lt;SPAN style="COLOR: #a31515"&gt;"en-GB"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;False&lt;/SPAN&gt;).TextInfo&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&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; titleCase.ToTitleCase(s)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Function&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;EXTENSION()&gt; _&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&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;Function&lt;/SPAN&gt; IsValidEmailAddress(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; s &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;) &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Boolean&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; regEx &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; System.Text.RegularExpressions.Regex( _&lt;/PRE&gt;&lt;PRE 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; &lt;SPAN style="COLOR: #a31515"&gt;"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$"&lt;/SPAN&gt;, _&lt;/PRE&gt;&lt;PRE 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; Text.RegularExpressions.RegexOptions.IgnoreCase)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&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; regEx.IsMatch(s)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Function&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Namespace&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;!--EndFragment--&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;FONT size=2&gt;Note that in the two method examples above, the first argument (and only argument in these examples) is of type string, this is because the first argument of any extension method must be of the type that you are extending.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P&gt;&lt;o:p&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;FONT size=2&gt;Now that we have this extension method module, all that we need to do in order to utilise it is import the necessary namespace into our declaring code and utilise the new methods:&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/o:p&gt;&lt;/P&gt;&lt;o:p&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;
&lt;DIV style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;Option&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Strict&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;On&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;Imports&lt;/SPAN&gt; ConsoleApplication1.MyExtensions.StringExtensions&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt; Module1&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Main()&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;'Output a proper case string&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"joe bloggs"&lt;/SPAN&gt;.ToProperCase)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;'Test for valid email address&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"joe.bloggs@somedomain.com"&lt;/SPAN&gt;.IsValidEmailAddress.ToString) &lt;SPAN style="COLOR: green"&gt;'Returns True&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"joe.bloggs-somedomain.com"&lt;/SPAN&gt;.IsValidEmailAddress.ToString) &lt;SPAN style="COLOR: green"&gt;'Returns False&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Console.ReadLine()&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Module&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;FONT color=#000000&gt;&lt;o:p&gt;&lt;/P&gt;&lt;/PRE&gt;&lt;/DIV&gt;Note also that these extension methods appear in Intellisense just as any other method of a type would, which makes this easier for developers of a team to discover new type methods:&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'"&gt;&lt;FONT color=#000000&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;&lt;/SPAN&gt;&lt;PRE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;IMG alt="Intellisense showing new Extension Methods" src="/images/blogs_vbcity_com/djjeavons/207/o_emis.gif" border=0&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;Another area where I think extension methods will prove extremely useful is when wishing to extend a custom class without creating a new version or inheriting from an existing version in order to add extra functionality.&lt;/SPAN&gt;&lt;/P&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/8956.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>Copy Source As HTML</title><link>http://blogs.vbcity.com/djjeavons/archive/2008/01/21/8955.aspx</link><pubDate>Mon, 21 Jan 2008 20:11:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2008/01/21/8955.aspx</guid><wfw:comment>http://blogs.vbcity.com/djjeavons/comments/8955.aspx</wfw:comment><comments>http://blogs.vbcity.com/djjeavons/archive/2008/01/21/8955.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.vbcity.com/djjeavons/comments/commentRss/8955.aspx</wfw:commentRss><trackback:ping>http://blogs.vbcity.com/djjeavons/services/trackbacks/8955.aspx</trackback:ping><description>&lt;P&gt;&lt;FONT face=Verdana size=2&gt;I&amp;nbsp;am not sure if this is old hat or not, but I regularly use the &lt;A href="http://www.jtleigh.com/people/colin/software/CopySourceAsHtml/"&gt;Copy Source As HTML&lt;/A&gt; addin in Visual Studio 2005 to post nicely formatted code samples. However, I have now got a new laptop loaded with Vista and VS 2008 and to my horror, my old install package of this great tool would not install as I did not have VS 2005 installed. &lt;/FONT&gt;&lt;FONT face=Verdana size=2&gt;I checked out Google and saw a number of articles that explained how you can get your VS 2005 addins to work with VS 2008 but they seemed like a bit of an effort. However, I then came across &lt;A href="http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/11/21/copy-source-as-html-copysourceashtml-for-visual-studio-2008-rtm.aspx"&gt;this post&lt;/A&gt; which has a link to a zip file that contains the necessary files to get this great tool working in VS 2008. Simply extract to the correct folder, restart VS 2008 and voila. Nice and simple :)&lt;/FONT&gt;&lt;/P&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/8955.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>Metallica's Sick of the Studio Tour</title><link>http://blogs.vbcity.com/djjeavons/archive/2007/07/10/8495.aspx</link><pubDate>Tue, 10 Jul 2007 09:00:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2007/07/10/8495.aspx</guid><wfw:comment>http://blogs.vbcity.com/djjeavons/comments/8495.aspx</wfw:comment><comments>http://blogs.vbcity.com/djjeavons/archive/2007/07/10/8495.aspx#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://blogs.vbcity.com/djjeavons/comments/commentRss/8495.aspx</wfw:commentRss><trackback:ping>http://blogs.vbcity.com/djjeavons/services/trackbacks/8495.aspx</trackback:ping><description>&lt;P&gt;&lt;FONT face=Verdana&gt;I was very lucky to attend the Metallica "Sick of the Studio Tour" on Sunday 8th July 2007 at Wembley Stadium, I was even luckier to be watching it from the comfort of Microsoft's Executive Box. There were a number of people there ranging from Microsoft Marketing people to Microsoft Student Partners. I also got to meet &lt;/FONT&gt;&lt;A href="http://sqlblogcasts.com/blogs/tonyrogerson/" target=_blank&gt;&lt;FONT face=Verdana&gt;Tony Rogerson&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana&gt; (a fellow MVP) and &lt;/FONT&gt;&lt;A href="http://www.danielmoth.com/Blog/" target=_blank&gt;&lt;FONT face=Verdana&gt;Daniel Moth&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana&gt;. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana&gt;It was the first time that I have been to Wembley since it has been rebuilt and I was extremely impressed. I had been a couple of times when I was younger and it still hasn't lost that feeling of grandeur when you are walking up to it. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana&gt;Metallica were awesome (as I expected) and the support bands (Mastodon, HIM and Bullet For My Valentine) were pretty good, although to be honest, it was the first time that I had heard their music. Below are some photos that I took, click to view a larger version.&lt;/FONT&gt; &lt;/P&gt;
&lt;P&gt; &lt;/P&gt;
&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://blogs.vbcity.com/images/blogs_vbcity_com/djjeavons/205/o_L1030019.JPG" target=_blank&gt;&lt;IMG title="Olympic Way" src="/images/blogs_vbcity_com/djjeavons/205/t_L1030019.JPG" border=0&gt;&lt;/A&gt; &lt;/TD&gt;
&lt;TD&gt;&lt;A href="http://blogs.vbcity.com/images/blogs_vbcity_com/djjeavons/205/o_L1030032.JPG" target=_blank&gt;&lt;IMG title="Bobby Moore Statue" src="/images/blogs_vbcity_com/djjeavons/205/t_L1030032.JPG" border=0&gt;&lt;/A&gt; &lt;/TD&gt;
&lt;TD&gt;&lt;A href="http://blogs.vbcity.com/images/blogs_vbcity_com/djjeavons/205/o_L1030062.JPG" target=_blank&gt;&lt;IMG title="Support Band" src="/images/blogs_vbcity_com/djjeavons/205/t_L1030062.JPG" border=0&gt;&lt;/A&gt; &lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://blogs.vbcity.com/images/blogs_vbcity_com/djjeavons/205/o_L1030149.JPG" target=_blank&gt;&lt;IMG title=Metallica src="/images/blogs_vbcity_com/djjeavons/205/t_L1030149.JPG" border=0&gt;&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;A href="http://blogs.vbcity.com/images/blogs_vbcity_com/djjeavons/205/o_L1030202.JPG" target=_blank&gt;&lt;IMG title=Metallica src="/images/blogs_vbcity_com/djjeavons/205/t_L1030202.JPG" border=0&gt;&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;A href="http://blogs.vbcity.com/images/blogs_vbcity_com/djjeavons/205/o_L1030204.JPG" target=_blank&gt;&lt;IMG title="James Hetfield" src="/images/blogs_vbcity_com/djjeavons/205/t_L1030204.JPG" border=0&gt;&lt;/A&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://blogs.vbcity.com/images/blogs_vbcity_com/djjeavons/205/o_L1030133.JPG" target=_blank&gt;&lt;IMG title="Guitar Hero" src="/images/blogs_vbcity_com/djjeavons/205/t_L1030133.JPG" border=0&gt;&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;A href="http://blogs.vbcity.com/images/blogs_vbcity_com/djjeavons/205/o_L1030134.JPG" target=_blank&gt;&lt;IMG title="Hidden Drinks Cabinet :)" src="/images/blogs_vbcity_com/djjeavons/205/t_L1030134.JPG" border=0&gt;&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;A href="http://blogs.vbcity.com/images/blogs_vbcity_com/djjeavons/205/o_L1030220.JPG" target=_blank&gt;&lt;IMG title="Brilliant Hostesses" src="/images/blogs_vbcity_com/djjeavons/205/t_L1030220.JPG" border=0&gt;&lt;/A&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/8495.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>View State Analyzers</title><link>http://blogs.vbcity.com/djjeavons/archive/2007/06/22/8457.aspx</link><pubDate>Fri, 22 Jun 2007 08:44:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2007/06/22/8457.aspx</guid><wfw:comment>http://blogs.vbcity.com/djjeavons/comments/8457.aspx</wfw:comment><comments>http://blogs.vbcity.com/djjeavons/archive/2007/06/22/8457.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.vbcity.com/djjeavons/comments/commentRss/8457.aspx</wfw:commentRss><trackback:ping>http://blogs.vbcity.com/djjeavons/services/trackbacks/8457.aspx</trackback:ping><description>&lt;TABLE cellSpacing=0 cellPadding=0 width="60%" border=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD style="FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=left colSpan=2&gt;I have recently been trimming down View State from some pages in an ASP.NET application and was looking around for tools that could help me decide where the majority of the View State was coming from. I have found some Gems and figured I would list them here in one place:&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD style="FONT-WEIGHT: bold; FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=left&gt;ASP.NET ViewState Helper&lt;/TD&gt;
&lt;TD style="FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=right&gt;&lt;A href="http://www.binaryfortress.com/aspnet-viewstate-helper/" target=_blank&gt;Homepage&lt;/A&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD style="FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=left colSpan=2&gt;This application can be downloaded either as a seperate Windows Application or as a Fiddler extension and is by far the better tool that I came across. The reason I like this tool the most is that it only concerns itself with aiding you in cutting down your page size, it doesn't come with any other bells and whistles. It simply displays a grid showing you the total page size, total view state size and then a percentage of both the view state and markup sizes that constitue the overall page size. You can then double click on a row in the grid that contains view state in order to see the view state decoded or in it's hierarchical state. This is an excellent tool and one that I would recommend. &lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD style="FONT-WEIGHT: bold; FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=left&gt;ViewStateAnalyzer&lt;/TD&gt;
&lt;TD style="FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=right&gt;&lt;A href="http://lab.aspitalia.com/26/ViewStateAnalyzer200.aspx#eng" target=_blank&gt;Homepage&lt;/A&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD style="FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=left colSpan=2&gt;When I first came across this via &lt;A href="http://weblogs.asp.net/scottgu/archive/2006/01/17/435745.aspx" target=_blank&gt;Scott Guthrie's Blog&lt;/A&gt; I thought that this would the tool I was looking for, unfortunately I didn't get on so well with this tool as it is a bit fiddly to use and does not give me the information that I require in an easy to understand format. Don't get me wrong, I am only basing my opinions on what my requirements were at the time and this tool may well be very useful for others so I certainly recommend checking it out. However, the big downside for me is that this tool only seems to work when your ASP.NET applications are running using the built-in web server (formerly known as Cassini) and not from applications running on IIS as it navigates to an address which is similar to the page you are looking at only with a ".vsax" extension and of course IIS spits out a 404. &lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD style="FONT-WEIGHT: bold; FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=left&gt;Nikhil's Web Development Helper&lt;/TD&gt;
&lt;TD style="FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=right&gt;&lt;A href="http://projects.nikhilk.net/Projects/WebDevHelper.aspx" target=_blank&gt;Homepage&lt;/A&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD style="FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=left colSpan=2&gt;I have used this tool quite a lot in the past and it is a great all purpose tool allowing you to do many things such as inspect the DOM of the page and view tracing and view state information. In order to use this tool to view ASP.NET information it must be installed as an HTTP Module (done by configuring the web.config file). The only problem I had with this tool is that sometimes the ASP.NET specific tools would stop working, I am not sure why and when it does work it is very useful but this is what led me to search for other view state tools. &lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD style="FONT-WEIGHT: bold; FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=left&gt;View State Decoder 2.1&lt;/TD&gt;
&lt;TD style="FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=right&gt;&lt;A href="http://www.pluralsight.com/tools.aspx" target=_blank&gt;Homepage&lt;/A&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD style="FONT-SIZE: x-small; FONT-FAMILY: Verdana" vAlign=top align=left colSpan=2&gt;This tool is similar to the ASP.NET ViewState Helper application in that it is an external Windows Application and it only concerns itself with View State, showing you the raw, decoded and hierarchical views. However, I could not get this tool to decode any view state I pointed it too so needless to say I cannot really comment on how good it is although I do like the fact that it is not bloated with loads of functionality. &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/8457.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>VS 2005 scared of mice</title><link>http://blogs.vbcity.com/djjeavons/archive/2006/09/26/6247.aspx</link><pubDate>Tue, 26 Sep 2006 09:04:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2006/09/26/6247.aspx</guid><description>&lt;P&gt;&lt;FONT face=Verdana size=2&gt;I have been experiencing a bit of a problem with Visual Studio 2005 lately which has had me perplexed for some time. When I create a new Windows or Console Application, Visual Studio goes through its motions and I am presented with either the forms designer or the standard module based on the type of project I chose. However, as soon as I hit the F5 button (no code modifications made) the project builds and then does absolutely nothing. The strange thing is that my main Web Site project is not affected by this behaviour, nor indeed is any other new web site projects. Yesterday, I finally got around to looking into this problem more thoroughly and found the darndest thing. The problem appears to be related to my Kensington Mouse (yes, you heard right), my mouse drivers were stopping my Windows or Console applications from building! So after uninstalling the mouse drivers, installing the standard Microsoft drivers and a reboot later, Visual Studio 2005 started to behave itself again.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;Who would have thought...?&lt;/FONT&gt;&lt;/P&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/6247.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>ASP.NET 2.0 and Application Restarts</title><link>http://blogs.vbcity.com/djjeavons/archive/2006/07/13/6095.aspx</link><pubDate>Thu, 13 Jul 2006 09:21:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2006/07/13/6095.aspx</guid><description>&lt;P&gt;&lt;FONT face=Verdana size=2&gt;I am currently working on converting my Companies website from Classic ASP and ASP.NET 1.1 to ASP.NET 2.0. We originally started converting most of our Administrative products from Classic ASP to ASP.NET 1.1 and this went very smoothly and worked fine. The reason we chose the Administrative products first is that it was less risky as users would not be faced with any code that may be broken and it is easier to talk with our staff than it is with clients in relation to technical problems. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;As soon as ASP.NET 2.0 was released we decided to convert from ASP.NET 1.1 to 2.0 and then continue the rest of the conversion in ASP.NET 2.0. Again, this was fine and everything was working smoothly. Now that we were more confident, we shipped a new product on our Website which was for use by our clients. This product is simply a Media Gallery where our clients can view photos and other media content of interest to them and uses some sophisticated searching mechanisms to make the product more unique. This is when problems started to arise as our staff upload images very frequently. We had in place a system whereby folders would be created for every "n" number of images to keep the number of files within a single folder to a reasonable amount. Once this product had been deployed and was being used more and more regularly, our Administrative users started getting session timeouts at irregular intervals and we simply didn't know what was causing the problem. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;Originally we thought that it was to do with our refresher technique (the refresher simply keeps the session alive) but this seemed to be working fine. So I started doing some research (still believing the problem to be with session timeouts) and couldn't find anything that explained the problem. I did however find other people that had experienced the same problem but answers to their posts seemed rather vague. One thing that I did learn however from this research&amp;nbsp;is that ASP.NET 2.0 uses a "File Change Notification" (FCN) technique to determine when files have changed and then re-compiles the changed files when they are next hit by a user and serves the previous file from it's cache to those users still using the original file. I thought that this was it, and looked at how I can overcome this problem, but after more research I found that ASP.NET 2.0 only restarts the application after 15 files have been changed (this can be modified in the machine.config file using the numRecompilesBeforeAppRestart setting) and this didn't really fit the problems that we were experiencing. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;Now that I knew about the FCN I decided to implement some debugging techniques that would hopefully help me out in finding the real cause of the problem. The first thing I did was to add a small piece of code to the Global.Asax's Application_End event&amp;nbsp;that would e-mail me each time the application restarted. Then I also used a program that would monitor the website directory for any changes and log them to a list box and text file. I used my &lt;/FONT&gt;&lt;A href="http://www.vbcity.com/forums/topic.asp?tid=99492" target=_top&gt;&lt;FONT face=Verdana size=2&gt;FileSystemWatcher demo program from a FAQ&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt; I wrote awhile ago. When I received the first e-mail notifying me that the application had restarted, I used the date and time value I had put in the body of the e-mail and tried to match it to an entry in my monitoring program, and lo and behold, there was indeed an entry. However, the entry was a little confusing at first as it wasn't a file change, instead it was a folder that had been renamed. I left this going for a day and each e-mail I got back matched to entries in my monitoring program showing folders either being renamed or deleted. I then ran some tests on my development server and each time I created and then deleted a folder, my development server would restart the application. To make things worse, we use Macromedia Dreamweaver for Classic ASP and when synchronising files between the development server and the live server, Macromedia Dreamweaver creates a temporary folder, read's it's timestamp and then deletes the folder hence another application restart (it does this as it has no way of reading the timestamp on the server for synchronisation purposes). This certainly explained why the restarts were so irregular.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;At least now I knew why it was happening, but I still didn't know how to fix it, until I stumbled on this &lt;/FONT&gt;&lt;A href="http://blogs.msdn.com/toddca/archive/2005/12/01/499144.aspx" target=_top&gt;&lt;FONT face=Verdana size=2&gt;blog entry&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt; by Todd Carter. It explains the problem in detail and also a workaround (not pretty but effective) using the Linkd command line utility to create an &lt;/FONT&gt;&lt;A href="http://support.microsoft.com/?kbid=205524" target=_top&gt;&lt;FONT face=Verdana size=2&gt;NTFS Junction folder&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt;. Apparently Junction folders do not alert the FCN to changes so you can create, rename and delete folders to your heart's content without having your application restart. I originally thought however that I would just create a Junction folder for the entire website folder, but alas, you can't do that as the application will still restart, instead, you need to create Junctions for each folder that you expect to change frequently, which probably won't be many and in my case ended up being four folders at the moment. The technique appears to work great as I haven't had an application restart for a few days now on a live server hit&amp;nbsp;thousands of times a day.&amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;Hope this information proves useful.&lt;/FONT&gt;&lt;/P&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/6095.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>Using a Validator to Validate a Check Box</title><link>http://blogs.vbcity.com/djjeavons/archive/2006/07/03/6069.aspx</link><pubDate>Mon, 03 Jul 2006 23:10:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2006/07/03/6069.aspx</guid><description>&lt;P&gt;&lt;FONT face=Verdana size=2&gt;Well, I must have spent about an hour today trying to figure out something that I assumed would be pretty trivial, in fact it was in the end but you know how it goes.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;I was creating a simple registration page for a website which requires that the user agrees to the Terms and Conditions of the site before they can submit their registration details. To begin with, I had a check box that the user would have to tick in order to state that they agreed and only when this check box was checked would the submit button be enabled, however, as I had disabled the submit button on the load of the page, all other required field validators stopped working. I assume as the submit button was disabled, ASP.NET didn't feel the need to continue wiring up the validation code necessary. So I thought that I would use one of the validation controls to ensure that the check box was checked thus no need to disable the submit button. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;After a little research, I found that the CustomValidator control would do the job for me, but nearly all of the examples I found seemed to either suggest that you had to write code in your code behind/beside file to register the necessary javascript on the page which I thought was a bit odd, or they just seemed overly complex. After a little playing around with various code snippets, I came up with what I thought was rather simple and not overly complex. Shame I didn't find it in the first place, it would have saved me a fair bit of time.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;To test this out, create a new web form file and add a check box to the page named "chkTandCs", then add a CustomValidator control next to it and finally a button. In the source of the web form, add the following javascript function to the head section:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000&gt;script&lt;/FONT&gt; &lt;FONT color=#ff0000&gt;language&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;="javascript"&lt;/FONT&gt; &lt;FONT color=#ff0000&gt;type&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;="text/javascript"&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New" color=#0000ff&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&lt;/FONT&gt;&lt;FONT face="Courier New"&gt; ValidateTandCs(source, args)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;args.IsValid = document.getElementById(&lt;/FONT&gt;&lt;FONT face="Courier New" color=#800000&gt;'&amp;lt;%= chkTandCs.ClientID %&amp;gt;&lt;%= chkTandCs.ClientID %&gt;'&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;).checked;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff&gt;&lt;BR&gt;&lt;/&lt; FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#800000&gt;script&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;Now, modify your CustomValidator control so that it reads:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;FONT color=#800000&gt;asp&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;:&lt;/FONT&gt;&lt;FONT color=#800000&gt;CustomValidator&lt;/FONT&gt; &lt;FONT color=#ff0000&gt;ID&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;="valTandCs"&lt;/FONT&gt; &lt;FONT color=#ff0000&gt;ClientValidationFunction&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;="ValidateTandCs"&lt;/FONT&gt; &lt;FONT color=#ff0000&gt;runat&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;="server"&lt;/FONT&gt; &lt;FONT color=#ff0000&gt;ErrorMessage&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;="Please accept Terms and Conditions before submitting."&amp;gt;&lt;/&lt; FONT&gt;&lt;FONT color=#800000&gt;asp&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;:&lt;/FONT&gt;&lt;FONT color=#800000&gt;CustomValidator&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Verdana color=#000000 size=2&gt;Note the ClientValidationFunction property is set to the javascript function ValidateTandCs. If the check box is checked then the function in effect returns True and the page is posted, otherwise, the ErrorMessage property of the CustomValidator is displayed and the page is not posted. This works in exactly the same way as a normal RequiredFieldValidator but allows you to validate a check box. In essence, you could use this technique to validate any server side control.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;To prove that it definitely worked, I added the following code to the click event of the button:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;Response.Write(&lt;FONT color=#800000&gt;"Page posted back"&lt;/FONT&gt;)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Verdana color=#000000 size=2&gt;Which only writes out to the page once it is posted to the server.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Verdana color=#000000 size=2&gt;I certainly learnt something new today :)&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/6069.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>DataSet Visualiser</title><link>http://blogs.vbcity.com/djjeavons/archive/2006/06/21/6060.aspx</link><pubDate>Wed, 21 Jun 2006 09:15:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2006/06/21/6060.aspx</guid><description>&lt;P&gt;&lt;FONT face=Verdana,Arial,Helvetica,sans-serif size=2&gt;This may be old hat to some, but I only found out about this neat little feature of VS 2005 yesterday and thought it was absolutely the best thing since sliced bread. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana,Arial,Helvetica,sans-serif size=2&gt;When you are debugging your code and you want to see the contents of a DataSet or a DataTable, one way is to use the Immediate Window and start entering commands such as "?myDataTable.Rows(0)(0).ToString" to read the first field in the first row etc. at least this is the way that I have been debugging programs in the past. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana,Arial,Helvetica,sans-serif size=2&gt;Yesterday I was having a small problem getting some code to work and was using my normal debugging techniques when my colleague said to me "I'm sure theres a function in 2005 that shows you the contents of a DataSet or DataTable". I of course laughed at him and called him a Liar (actually, I said worse than that but it has no place here), but he swore it was true and so I added a breakpoint on my DataTable variable and when the breakpoint hit, I hovered my mouse over the DataTable ready to prove that I was indeed right and he obviously had no idea what he was talking about when he then triumphantly pointed at the little magnifying glass in the quick watch tooltip:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana,Arial,Helvetica,sans-serif size=2&gt;&amp;nbsp;&lt;/FONT&gt;&lt;IMG title="Quickwatch Tooltip" src="/upload/djjeavons/dsvs1.gif" border=0&gt; &lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana,Arial,Helvetica,sans-serif size=2&gt;So I clicked on this magnifying glass thinking that it probably didn't do much (I had never noticed it before) when it came up with the menu option "DataSet Visualiser":&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;IMG title="Quickwatch Tooltip DataSet Visualiser" src="/upload/djjeavons/dsvs2.gif" border=0&gt; &lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana,Arial,Helvetica,sans-serif size=2&gt;Then clicking on the menu option produced the following window: &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;IMG title="DataSet Visualiser" src="/upload/djjeavons/dsvs3.gif" border=0&gt; &lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana,Arial,Helvetica,sans-serif size=2&gt;which as you can see, shows the entire contents of the DataTable that I was working with. The other cool feature is that if you are using a DataSet that contains many tables, then the Table drop down will contain the names of all tables within the DataSet and you only need change the Table for it to then refresh the grid and show the contents of the selected table. Neat. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana,Arial,Helvetica,sans-serif size=2&gt;You also have the same functionality when performing a Quick Watch or when adding your variable to the Watch Window. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana,Arial,Helvetica,sans-serif size=2&gt;So after my initial "Wow" moment, I was left with only one thing to do, apologise profusely to my colleague and promise to listen to him in the future.&lt;/FONT&gt;&lt;/P&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/6060.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>Create a Custom Paging User Control</title><link>http://blogs.vbcity.com/djjeavons/archive/2006/03/09/5880.aspx</link><pubDate>Thu, 09 Mar 2006 10:39:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2006/03/09/5880.aspx</guid><description>There are many times when you need to display a large amount of data to a user. When this need arises, you could of course use a DataGrid and make use of the in-built paging mechanism which makes paging a breeze. However, what if you can't use a DataGrid? Maybe the data you are displaying does not fit the structure of a DataGrid. Fortunately, we can borrow the DataGrid's paging mechanism and use it to create our own paging control which will allow us to add paging capabilities to a wider range of controls.&lt;p&gt;This post aims to give you an alternative that will allow you to create your own custom paging control which can be bound to any control that supports the  IEnumerable Interface. Another goal of this control is to allow for the paging of any data that again supports the IEnumerable interface. So rather than only paging data from a Database (through the use of a DataTable or DataView), you can also bind an ArrayList for example to the paging control and page through the contents of the ArrayList or even create your own specialised class' that implements the IEnumerable interface and page through that.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Create the User Control&lt;/b&gt;&lt;/p&gt;First, we need to create the user control, so add a new User Control item to your project and name it "Paging". Then add the following controls (you may want to add them to a table or div, the choice is yours):&lt;p&gt;&lt;table border="0" cellspacing="2" cellpadding="2"&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Control Type&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;ID&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Text&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;LinkButton&lt;/td&gt;&lt;td&gt;lkbMoveFirst&lt;/td&gt;&lt;td&gt;Move First&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;LinkButton&lt;/td&gt;&lt;td&gt;lkbMovePrevious&lt;/td&gt;&lt;td&gt;Move Previous&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Label&lt;/td&gt;&lt;td&gt;lblPageInformation&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;LinkButton&lt;/td&gt;&lt;td&gt;lkbMoveNext&lt;/td&gt;&lt;td&gt;Move Next&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;LinkButton&lt;/td&gt;&lt;td&gt;lkbMoveLast&lt;/td&gt;&lt;td&gt;Move Last&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;b&gt;Add the Paging Code&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Copy the following code into the code-behind file of the Paging control:&lt;/p&gt;&lt;p&gt;
&lt;style type="text/css"&gt;
.cf { font-family: Verdana; font-size: 9pt; margin-left:20px;}
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: green; }
&lt;/style&gt;
&lt;div class="cf"&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Option&lt;/span&gt; &lt;span class="cb1"&gt;Strict&lt;/span&gt; &lt;span class="cb1"&gt;On&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Partial Class&lt;/span&gt; paging&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Inherits&lt;/span&gt; System.Web.UI.UserControl&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb2"&gt;'Member variables&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Private&lt;/span&gt; _dataSource &lt;span class="cb1"&gt;As&lt;/span&gt; IEnumerable&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Private&lt;/span&gt; _pageSize &lt;span class="cb1"&gt;As&lt;/span&gt; Int32 = 10&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Private&lt;/span&gt; _pageNumber &lt;span class="cb1"&gt;As&lt;/span&gt; Int32 = 0&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Private&lt;/span&gt; _allowPaging &lt;span class="cb1"&gt;As&lt;/span&gt; &lt;span class="cb1"&gt;Boolean&lt;/span&gt; = &lt;span class="cb1"&gt;True&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Private&lt;/span&gt; _pageCount &lt;span class="cb1"&gt;As&lt;/span&gt; Int32 = 0&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Private&lt;/span&gt; pageSource &lt;span class="cb1"&gt;As&lt;/span&gt; PagedDataSource &lt;span class="cb2"&gt;'Provides the paging functionality.&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb2"&gt;'An event that is raised each time the page is changed.&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Public&lt;/span&gt; &lt;span class="cb1"&gt;Event&lt;/span&gt; PageIndexChanged(&lt;span class="cb1"&gt;ByVal&lt;/span&gt; sender &lt;span class="cb1"&gt;As&lt;/span&gt; System.Object, &lt;span class="cb1"&gt;ByVal&lt;/span&gt; e &lt;span class="cb1"&gt;As&lt;/span&gt; System.EventArgs)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Public&lt;/span&gt; &lt;span class="cb1"&gt;Property&lt;/span&gt; DataSource() &lt;span class="cb1"&gt;As&lt;/span&gt; IEnumerable&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Get&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Return&lt;/span&gt; _dataSource&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Get&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Set&lt;/span&gt;(&lt;span class="cb1"&gt;ByVal&lt;/span&gt; value &lt;span class="cb1"&gt;As&lt;/span&gt; IEnumerable)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _dataSource = value&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Set&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Property&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Public&lt;/span&gt; &lt;span class="cb1"&gt;Property&lt;/span&gt; PageSize() &lt;span class="cb1"&gt;As&lt;/span&gt; Int32&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Get&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Return&lt;/span&gt; _pageSize&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Get&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Set&lt;/span&gt;(&lt;span class="cb1"&gt;ByVal&lt;/span&gt; value &lt;span class="cb1"&gt;As&lt;/span&gt; Int32)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _pageSize = value&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;'Store the _pageSize value in ViewState&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ViewState("PageSize") = _pageSize&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Set&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Property&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Public&lt;/span&gt; &lt;span class="cb1"&gt;Property&lt;/span&gt; PageNumber() &lt;span class="cb1"&gt;As&lt;/span&gt; Int32&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Get&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Return&lt;/span&gt; _pageNumber&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Get&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Set&lt;/span&gt;(&lt;span class="cb1"&gt;ByVal&lt;/span&gt; value &lt;span class="cb1"&gt;As&lt;/span&gt; Int32)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _pageNumber = value&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;'Store the _pageNumber value in ViewState&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ViewState("PageNumber") = _pageNumber&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Set&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Property&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Public&lt;/span&gt; &lt;span class="cb1"&gt;ReadOnly&lt;/span&gt; &lt;span class="cb1"&gt;Property&lt;/span&gt; PageCount() &lt;span class="cb1"&gt;As&lt;/span&gt; Int32&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Get&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Return&lt;/span&gt; _pageCount&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Get&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Property&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Public&lt;/span&gt; &lt;span class="cb1"&gt;Property&lt;/span&gt; AllowPaging() &lt;span class="cb1"&gt;As&lt;/span&gt; &lt;span class="cb1"&gt;Boolean&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Get&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Return&lt;/span&gt; _allowPaging&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Get&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Set&lt;/span&gt;(&lt;span class="cb1"&gt;ByVal&lt;/span&gt; value &lt;span class="cb1"&gt;As&lt;/span&gt; &lt;span class="cb1"&gt;Boolean&lt;/span&gt;)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _allowPaging = value&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;'Store the _allowPaging value in ViewState&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ViewState("AllowPaging") = _allowPaging&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Set&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Property&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Private&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt; Paging()&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;'Create a new instance of the pageSource if required&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;If&lt;/span&gt; pageSource &lt;span class="cb1"&gt;Is&lt;/span&gt; &lt;span class="cb1"&gt;Nothing&lt;/span&gt; &lt;span class="cb1"&gt;Then&lt;/span&gt; pageSource = &lt;span class="cb1"&gt;New&lt;/span&gt; PagedDataSource&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;'Setup the pageSource &lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;With&lt;/span&gt; pageSource&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; .DataSource = _dataSource&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; .PageSize = _pageSize&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; .AllowPaging = _allowPaging&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;If&lt;/span&gt; _pageNumber &amp;gt; .PageCount &lt;span class="cb1"&gt;Then&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Throw&lt;/span&gt; &lt;span class="cb1"&gt;New&lt;/span&gt; ArgumentOutOfRangeException&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Else&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; .CurrentPageIndex = _pageNumber&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;If&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;'Display page information&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; lblPageInformation.Text = "Page " &amp;amp; (.CurrentPageIndex + 1).ToString &amp;amp; " of " &amp;amp; .PageCount.ToString&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;'Enable/Disable the navigation buttons based on where we are in the paging source.&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; lkbMoveFirst.Enabled = &lt;span class="cb1"&gt;Not&lt;/span&gt; .IsFirstPage&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; lkbMovePrevious.Enabled = &lt;span class="cb1"&gt;Not&lt;/span&gt; .IsFirstPage&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; lkbMoveNext.Enabled = &lt;span class="cb1"&gt;Not&lt;/span&gt; .IsLastPage&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; lkbMoveLast.Enabled = &lt;span class="cb1"&gt;Not&lt;/span&gt; .IsLastPage&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;'Store the current page count in ViewState&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ViewState("PageCount") = .PageCount - 1&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;With&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Private&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt; Navigation_Click(&lt;span class="cb1"&gt;ByVal&lt;/span&gt; sender &lt;span class="cb1"&gt;As&lt;/span&gt; System.Object, &lt;span class="cb1"&gt;ByVal&lt;/span&gt; e &lt;span class="cb1"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="cb1"&gt;Handles&lt;/span&gt; _&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;lkbMoveFirst.Click, lkbMovePrevious.Click, lkbMoveNext.Click, lkbMoveLast.Click&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;'Retrieve instance data from ViewState if available&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;If&lt;/span&gt; ViewState("PageSize") IsNot &lt;span class="cb1"&gt;Nothing&lt;/span&gt; &lt;span class="cb1"&gt;Then&lt;/span&gt; _pageSize = Int32.Parse(ViewState("PageSize").ToString)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;If&lt;/span&gt; ViewState("PageNumber") IsNot &lt;span class="cb1"&gt;Nothing&lt;/span&gt; &lt;span class="cb1"&gt;Then&lt;/span&gt; _pageNumber = Int32.Parse(ViewState("PageNumber").ToString)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;If&lt;/span&gt; ViewState("PageCount") IsNot &lt;span class="cb1"&gt;Nothing&lt;/span&gt; &lt;span class="cb1"&gt;Then&lt;/span&gt; _pageCount = Int32.Parse(ViewState("PageCount").ToString)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;If&lt;/span&gt; ViewState("AllowPaging") IsNot &lt;span class="cb1"&gt;Nothing&lt;/span&gt; &lt;span class="cb1"&gt;Then&lt;/span&gt; _allowPaging = &lt;span class="cb1"&gt;Boolean&lt;/span&gt;.Parse(ViewState("AllowPaging").ToString)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&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 class="cb2"&gt;'Determine which control initiated the Navigation_Click&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&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 class="cb1"&gt;Select&lt;/span&gt; &lt;span class="cb1"&gt;Case&lt;/span&gt; &lt;span class="cb1"&gt;CType&lt;/span&gt;(sender, LinkButton).ID.ToLower&lt;/p&gt;
&lt;p class="cl"&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; &lt;span class="cb1"&gt;Case&lt;/span&gt; "lkbmovefirst"&lt;/p&gt;
&lt;p class="cl"&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; _pageNumber = 0&lt;/p&gt;
&lt;p class="cl"&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; &lt;span class="cb1"&gt;Case&lt;/span&gt; "lkbmoveprevious"&lt;/p&gt;
&lt;p class="cl"&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; _pageNumber -= 1&lt;/p&gt;
&lt;p class="cl"&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; &lt;span class="cb1"&gt;Case&lt;/span&gt; "lkbmovenext"&lt;/p&gt;
&lt;p class="cl"&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; _pageNumber += 1&lt;/p&gt;
&lt;p class="cl"&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; &lt;span class="cb1"&gt;Case&lt;/span&gt; "lkbmovelast"&lt;/p&gt;
&lt;p class="cl"&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; _pageNumber = pageCount&lt;/p&gt;
&lt;p class="cl"&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 class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Select&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&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 class="cb2"&gt;'Update the ViewState values&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&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; ViewState("PageNumber") = _pageNumber&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&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 class="cb2"&gt;'Raise the PageIndexedChanged event&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&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 class="cb1"&gt;RaiseEvent&lt;/span&gt; PageIndexChanged(&lt;span class="cb1"&gt;Me&lt;/span&gt;, &lt;span class="cb1"&gt;Nothing&lt;/span&gt;)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Public&lt;/span&gt; &lt;span class="cb1"&gt;Function&lt;/span&gt; GetPage() &lt;span class="cb1"&gt;As&lt;/span&gt; IEnumerable&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Paging()&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Return&lt;/span&gt; pageSource&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Function&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Class&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;Now to test the control.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Add a new web form and drop the paging control onto the page. You may need to wire up the paging control to your code-behind file using:&lt;/p&gt;
&lt;div class="cf"&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Protected&lt;/span&gt; &lt;span class="cb1"&gt;WithEvents&lt;/span&gt; Paging1 &lt;span class="cb1"&gt;As&lt;/span&gt; paging&lt;/p&gt;
&lt;/div&gt;&lt;p&gt;This first test will show how you can page through data from a database using the Paging control and display that data in a ListBox. I have used the Northwind database in SQL Server for this example. Add the following code to your code-behind file:&lt;/p&gt;
&lt;div class="cf"&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Protected&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt; Page_Load(&lt;span class="cb1"&gt;ByVal&lt;/span&gt; sender &lt;span class="cb1"&gt;As&lt;/span&gt; &lt;span class="cb1"&gt;Object&lt;/span&gt;, &lt;span class="cb1"&gt;ByVal&lt;/span&gt; e &lt;span class="cb1"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="cb1"&gt;Handles&lt;/span&gt; &lt;span class="cb1"&gt;Me&lt;/span&gt;.Load&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Dim&lt;/span&gt; connection &lt;span class="cb1"&gt;As&lt;/span&gt; &lt;span class="cb1"&gt;New&lt;/span&gt; System.Data.SqlClient.SqlConnection("Data Source=(local);Initial Catalog=Northwind;UID=xxx;Password=xxx")&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Dim&lt;/span&gt; adapter &lt;span class="cb1"&gt;As&lt;/span&gt; &lt;span class="cb1"&gt;New&lt;/span&gt; System.Data.SqlClient.SqlDataAdapter("SELECT * FROM Customers", connection)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Dim&lt;/span&gt; dt &lt;span class="cb1"&gt;As&lt;/span&gt; &lt;span class="cb1"&gt;New&lt;/span&gt; System.Data.DataTable&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; adapter.Fill(dt)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;'You can set your desired page size here or accept the default of 10 records.&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Me&lt;/span&gt;.Paging1.DataSource = dt.DefaultView&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.Items.Clear()&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;'Populate with first n items (n = page size)&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;If&lt;/span&gt; &lt;span class="cb1"&gt;Not&lt;/span&gt; Page.IsPostBack &lt;span class="cb1"&gt;Then&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataSource = Paging1.GetPage&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataTextField = "ContactName"&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataValueField = "CustomerID"&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataBind()&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;If&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Protected&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt; Paging1_PageIndexChanged(&lt;span class="cb1"&gt;ByVal&lt;/span&gt; sender &lt;span class="cb1"&gt;As&lt;/span&gt; &lt;span class="cb1"&gt;Object&lt;/span&gt;, &lt;span class="cb1"&gt;ByVal&lt;/span&gt; e &lt;span class="cb1"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="cb1"&gt;Handles&lt;/span&gt; Paging1.PageIndexChanged&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataSource = Paging1.GetPage&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataTextField = "ContactName"&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataValueField = "CustomerID"&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataBind()&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;&lt;p&gt;In the above example, you will see that the DataSource of the paging control is set on Page Load and if the page is not a post back then the DataSource of the ListBox is set to the GetPage method of the paging control which returns the IEnumerable interface. Each time the page is changed, the PageIndexChanged event is raised and again, the DataSource of the ListBox is set to the GetPage method of the paging control.&lt;/p&gt;&lt;p&gt;The next example shows how you can perform the same paging but using an ArrayList instead of a DataTable. The same concept applies as in the first example:&lt;/p&gt;
&lt;div class="cf"&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Protected&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt; Page_Load(&lt;span class="cb1"&gt;ByVal&lt;/span&gt; sender &lt;span class="cb1"&gt;As&lt;/span&gt; &lt;span class="cb1"&gt;Object&lt;/span&gt;, &lt;span class="cb1"&gt;ByVal&lt;/span&gt; e &lt;span class="cb1"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="cb1"&gt;Handles&lt;/span&gt; &lt;span class="cb1"&gt;Me&lt;/span&gt;.Load&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Dim&lt;/span&gt; myData &lt;span class="cb1"&gt;As&lt;/span&gt; &lt;span class="cb1"&gt;New&lt;/span&gt; ArrayList&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;For&lt;/span&gt; i &lt;span class="cb1"&gt;As&lt;/span&gt; Int32 = 1 &lt;span class="cb1"&gt;To&lt;/span&gt; 100&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; myData.Add(i)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Next&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Paging1.DataSource = myData&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;If&lt;/span&gt; &lt;span class="cb1"&gt;Not&lt;/span&gt; Page.IsPostBack &lt;span class="cb1"&gt;Then&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataSource = Paging1.GetPage&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataBind()&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;If&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Protected&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt; Paging1_PageIndexChanged(&lt;span class="cb1"&gt;ByVal&lt;/span&gt; sender &lt;span class="cb1"&gt;As&lt;/span&gt; &lt;span class="cb1"&gt;Object&lt;/span&gt;, &lt;span class="cb1"&gt;ByVal&lt;/span&gt; e &lt;span class="cb1"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="cb1"&gt;Handles&lt;/span&gt; Paging1.PageIndexChanged&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataSource = Paging1.GetPage&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ListBox1.DataBind()&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;End&lt;/span&gt; &lt;span class="cb1"&gt;Sub&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;&lt;p&gt;In the above examples, the data has been bound to a ListBox, but as mentioned earlier, you can use the Paging control to bind to any control that supports the IEnumerable interface. Another thing to bear in mind is that you could also request an enumerator from the GetPage method and enumerate the page's data programatically without binding the Paging control to a web control. For example, if the Paging controls DataSource was set to a DataView then the following example, would enumerate through the current page data:&lt;/p&gt;
&lt;div class="cf"&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Dim&lt;/span&gt; myEnumerator &lt;span class="cb1"&gt;As&lt;/span&gt; IEnumerator = Paging1.GetPage.GetEnumerator&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Dim&lt;/span&gt; dv &lt;span class="cb1"&gt;As&lt;/span&gt; Data.DataRowView = &lt;span class="cb1"&gt;Nothing&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Do&lt;/span&gt; &lt;span class="cb1"&gt;While&lt;/span&gt; myEnumerator.MoveNext = &lt;span class="cb1"&gt;True&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dv = &lt;span class="cb1"&gt;CType&lt;/span&gt;(myEnumerator.Current, Data.DataRowView)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&lt;span class="cb1"&gt;Loop&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I hope this proves useful to somebody.&lt;/p&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/5880.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>Migrating VS 2003 ASP.NET Projects to ASP.NET 2.0</title><link>http://blogs.vbcity.com/djjeavons/archive/2006/03/08/5878.aspx</link><pubDate>Wed, 08 Mar 2006 22:32:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2006/03/08/5878.aspx</guid><description>Well, having spent the last few days trying to migrate our website from Classic ASP and ASP.NET 1.1 to ASP.NET 2.0, I had just about given up.
&lt;P&gt;A little background. The website I am talking of was written using classic ASP and is the backbone of the company I work for. Now, this website, does not actually need to be upgraded in order to suceed but the development costs and turnaround times of new features would be better served by using ASP.NET. So, about eight months ago, we decided to write all new products for the website in ASP.NET 1.1 with a view to upgrading these products and also classic ASP products to ASP.NET 2.0 when Visual Studio 2005 was released. So far so good. The path we chose was to have a single web project for each product which meant that if a product required updating, we would only need to update the .aspx pages and code behind files and then compile to a single DLL for that product and then upload those changes along with the DLL and the rest would be untouched and therefore, no chance of breaking something unintentionally. This has now worked fine for around five months.&lt;/P&gt;
&lt;P&gt;Now came the time for upgrading these products into VS 2005 and I was more than perplexed to find that VS 2005 does not allow the same web project model as VS 2003 meaning that we would have to use the new Website Model which didn't really fit our needs, as most pages would be compiled into a single DLL with possibly support class' being compiled into seperate DLLs, but still not really following the structure that we had implemented and become comfortable with.&lt;/P&gt;
&lt;P&gt;Now, you may be wondering where I am going with this ;-) I did a little research (and no doubt most of you would have found the same resources, but to save you the heartache...) and found a great blog entry from &lt;A title="Scott Guthrie" href="http://weblogs.asp.net/scottgu/" target=_blank&gt;Scott Guthrie&lt;/A&gt; which details the excellent work that Microsoft has done to correct the issue of omitting this project template from VS 2005 in the first place. There is now a downloadable (albeit, still in beta stage) project template that gives you the same ASP.NET project template that you had in VS 2003 while still benefiting from all of the great enhancements in VS 2005 and the .NET Framework 2.0. I encourage anybody faced with the same problem to check out the &lt;A href="http://weblogs.asp.net/scottgu/archive/2005/12/16/433374.aspx" target=_blank&gt;First Preview Download of VS 2005 Web Application Project Model Now Available&lt;/A&gt; and the download and tutorial links available at &lt;A href="http://webproject.scottgu.com/Download.aspx" target=_blank&gt;Visual Studio 2005 Web Application Project Preview&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;I still have some testing to do, but I have successfully migrated the project over to ASP.NET 2.0 in around 3 hours and there is quite a bit of code so I was quite pleased with the time it took, but I am not happy with the fact that I now have ASP.NET 1.1 .aspx and .vb pages that don't make use of partial classes and such sitting in an ASP.NET 2.0 project. You can of course choose to upgrade each project to a Web Application but I found that this didn't work quite so well as you would end up with some page declaration code in your code behind file and some in the .designer file which I am not too happy about. Instead, I have decided to take a longer approach to the migration in that I have created the same structure as I had in VS 2003 and will manually copy the code over bit by bit (admittedly, this should be quite quick due to the fact that of the 11 current products, 4 are support products with no interface and the rest will only require that I create the pages manually) and then copy the markup and code over. I do think I will be turning the XHTML checking off though for this stage of the migration as I don't know that I can face being told that I have hundreds of lines of code that are deprecated or not surrounded in quotes etc. ;)&lt;/P&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/5878.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>ListViewGroup Intuitive?</title><link>http://blogs.vbcity.com/djjeavons/archive/2006/02/27/5851.aspx</link><pubDate>Mon, 27 Feb 2006 15:52:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2006/02/27/5851.aspx</guid><description>I was looking at the ListView control in VS 2005 today and noticed the new addition of the ListViewGroup object. I didn't immediately know what this was but 
intellisense's tooltip states that it "Represents a group of items displayed within a ListView control" and this was enough to peak my interest (I'm easily 
pleased). For those like myself that are unaware of what a ListView group is, the following screen shot from Windows Explorer shows ListViewGroup's in 
action:&lt;p&gt;&lt;div align="center"&gt;&lt;br&gt;&lt;img src="http://blogs.vbcity.com/upload/djjeavons/explorer.jpg" title="Example of the ListViewGroup in Windows Explorer" 
border="0"&gt;&lt;/p&gt;&lt;b&gt;Example of the ListViewGroup in Windows Explorer&lt;/b&gt;&lt;/div&gt;&lt;br&gt;&lt;p&gt;So I thought I would have a quick go at adding these ListViewGroup's to a 
ListView control to see how easy it was. Well, it certainly wasn't quick and I must admit, not very intuitive. Being one of those people that expect 
something to work in a pre-defined way, I didn't bother looking at the documentation and went straight to coding. I created a ListView control, set it's view 
mode to details and commenced to add some columns to it. I then declared a new ListViewGroup and then started adding ListViewItem objects to the 
ListViewGroups Items collection (seemed reasonable enough to me). Once I had added all of the items I wanted to the group, I then added the group to the 
ListView control using the ListView.Groups.Add method. Rubbing my hands eagerly, I pressed F5 and hey presto, empty ListView :-(&lt;/p&gt;&lt;p&gt;Returning to the code, 
I checked to ensure I hadn't done anything stupid, like create the ListViewItem's but forget to add them to the Group (never done that before ;)) but the 
code looked fine. So I gave in and pressed F1 on the ListViewGroup and was surprised at how complex the example in the help documentation seemed. After all, 
I only wanted to add a couple of groups to a ListView and add some items to each group. So then I decided to create a new project and add the groups and 
items to the ListView control through the properties window and then looked at the .designer file to see how it had been done and to my surprise, it is 
relatively simple. The problem I had was in thinking of the ListViewGroup as a collection of ListViewItems and that each ListViewGroup would then be added to 
the ListView Control when in fact, you simply add the ListViewItem's like you normally would to the ListView control but if you want them to be in a group, 
you then set the Group property of the ListViewItem to the group that you want the item to be associated to.&lt;/p&gt;&lt;p&gt;So after all of that, I finally had a 
working example of using ListViewGroup's. Below is the code that I created to give me a similar output to that in the above screen shot. Just copy it into 
the Form_Load event. Also, beware that the code only works for Windows XP and Windows 2003 (this is what I ascertained from the help 
documentation).&lt;/p&gt;&lt;br&gt;&lt;br&gt;&lt;p&gt;
&lt;table border="0" cellspacing="0" cellpadding="0" border="0" width="100%"&gt;
&lt;tr&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;
&lt;span style="font-size:8pt;font-family:courier"&gt;
&lt;span style="color:#008000"&gt;'Create the ListView control and add it to the Form's controls collection.&lt;/span&gt;&lt;br&gt;
&lt;span style="color:#0000FF"&gt;Dim&lt;/span&gt; lv &lt;span style="color:#0000FF"&gt;As&lt;/span&gt; &lt;span style="color:#0000FF"&gt;New&lt;/span&gt; ListView&lt;br&gt;
lv.Dock = DockStyle.Fill&lt;br&gt;&lt;br&gt;
&lt;span style="color:#0000FF"&gt;Me&lt;/span&gt;.Controls.Add(lv)&lt;br&gt;&lt;br&gt;
&lt;span style="color:#008000"&gt;'Setup the ListView control.&lt;/span&gt;&lt;br&gt;
&lt;span style="color:#0000FF"&gt;With&lt;/span&gt; lv&lt;br&gt;
&lt;span style="color:#008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'Add column headers to the ListView.&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Columns.Add(&lt;span style="color:#800000"&gt;"Name"&lt;/span&gt;, 200, HorizontalAlignment.Left)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Columns.Add(&lt;span style="color:#800000"&gt;"Type"&lt;/span&gt;, 150, HorizontalAlignment.Left)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Columns.Add(&lt;span style="color:#800000"&gt;"Total Size"&lt;/span&gt;, 100, HorizontalAlignment.Right)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Columns.Add(&lt;span style="color:#800000"&gt;"Free Space"&lt;/span&gt;, 100, HorizontalAlignment.Right)&lt;br&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000"&gt;'Allow the columns to be re-ordered at run time&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.AllowColumnReorder = &lt;span style="color:#0000FF"&gt;True&lt;/span&gt;&lt;br&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000"&gt;'Set the initial display mode to Details&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.View = View.Details&lt;br&gt;
&lt;span style="color:#0000FF"&gt;End With&lt;/span&gt;&lt;br&gt;&lt;br&gt;
&lt;span style="color:#008000"&gt;'Create the "Hard Disk Drives" group&lt;/span&gt;&lt;br&gt;
&lt;span style="color:#0000FF"&gt;Dim&lt;/span&gt; hddGroup &lt;span style="color:#0000FF"&gt;As New&lt;/span&gt; ListViewGroup(&lt;span style="color:#800000"&gt;"Hard Disk 
Drives"&lt;/span&gt;, HorizontalAlignment.Left)&lt;br&gt;
hddGroup.Name = &lt;span style="color:#800000"&gt;"HDDGroup"&lt;/span&gt;&lt;br&gt;&lt;br&gt;
&lt;span style="color:#008000"&gt;'Create the "Devices with Removable Storage" group&lt;/span&gt;&lt;br&gt;
&lt;span style="color:#0000FF"&gt;Dim&lt;/span&gt; removableGroup &lt;span style="color:#0000FF"&gt;As New&lt;/span&gt; ListViewGroup(&lt;span style="color:#800000"&gt;"Devices with 
Removable Storage"&lt;/span&gt;, HorizontalAlignment.Left)&lt;br&gt;
removableGroup.Name = &lt;span style="color:#800000"&gt;"RemovableStorage"&lt;/span&gt;&lt;br&gt;&lt;br&gt;
&lt;span style="color:#008000"&gt;'Add the hddGroup and removableGroup ListViewGroups to the ListView control&lt;/span&gt;&lt;br&gt;
lv.Groups.Add(hddGroup)&lt;br&gt;
lv.Groups.Add(removableGroup)&lt;br&gt;&lt;br&gt;
&lt;span style="color:#008000"&gt;'Create a ListViewItem for each drive and add to the ListView control&lt;/span&gt;&lt;br&gt;
&lt;span style="color:#0000FF"&gt;Dim&lt;/span&gt; li &lt;span style="color:#0000FF"&gt;As&lt;/span&gt; ListViewItem&lt;br&gt;
&lt;span style="color:#0000FF"&gt;Dim&lt;/span&gt; volumeLabel &lt;span style="color:#0000FF"&gt;As String&lt;/span&gt; = &lt;span style="color:#0000FF"&gt;String&lt;/span&gt;.Empty&lt;br&gt;&lt;br&gt;
&lt;span style="color:#008000"&gt;'Enumerate through the drives collection and add each drive name, type, total size and free space&lt;/span&gt;&lt;br&gt;
&lt;span style="color:#008000"&gt;'to the ListView control. A check is made to determine the type of drive which then determines&lt;/span&gt;&lt;br&gt;
&lt;span style="color:#008000"&gt;'which group to assign to the ListViewItem.&lt;/span&gt;&lt;br&gt;
&lt;span style="color:#0000FF"&gt;For Each&lt;/span&gt; driveName &lt;span style="color:#0000FF"&gt;As&lt;/span&gt; System.IO.DriveInfo &lt;span style="color:#0000FF"&gt;In 
My&lt;/span&gt;.Computer.FileSystem.Drives&lt;br&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;li = &lt;span style="color:#0000FF"&gt;New&lt;/span&gt; ListViewItem&lt;br&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000FF"&gt;If&lt;/span&gt; driveName.IsReady = &lt;span style="color:#0000FF"&gt;False OrElse&lt;/span&gt; 
driveName.VolumeLabel.Length = 0 _&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000FF"&gt;Then&lt;/span&gt; volumeLabel = driveName.DriveType.ToString &lt;span style="color:#0000FF"&gt;Else&lt;/span&gt; 
volumeLabel = driveName.VolumeLabel&lt;br&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;li.Text = volumeLabel &amp; &lt;span style="color:#800000"&gt;" ("&lt;/span&gt; &amp; driveName.Name.Substring(0, 2) &amp; &lt;span 
style="color:#800000"&gt;")"&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;li.SubItems.Add(driveName.DriveType.ToString)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000FF"&gt;If&lt;/span&gt; driveName.IsReady = &lt;span style="color:#0000FF"&gt; False Then&lt;/span&gt; li.SubItems.Add(&lt;span 
style="color:#800000"&gt;"0"&lt;/span&gt;) &lt;span style="color:#0000FF"&gt;Else&lt;/span&gt; li.SubItems.Add(driveName.TotalSize.ToString)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000FF"&gt;If&lt;/span&gt; driveName.IsReady = &lt;span style="color:#0000FF"&gt;False Then&lt;/span&gt; li.SubItems.Add(&lt;span 
style="color:#800000"&gt;"0"&lt;/span&gt;) &lt;span style="color:#0000FF"&gt;Else&lt;/span&gt; li.SubItems.Add(driveName.TotalFreeSpace.ToString)&lt;br&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000"&gt;'Determine the drive type and assign the relevant group to the current ListViewItem Group 
property&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000FF"&gt;Select Case&lt;/span&gt; driveName.DriveType&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000FF"&gt;Case&lt;/span&gt; IO.DriveType.Fixed&lt;br&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;li.Group = hddGroup&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000FF"&gt;Case&lt;/span&gt; IO.DriveType.Removable, IO.DriveType.CDRom&lt;br&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;li.Group = removableGroup&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000FF"&gt;End Select&lt;/span&gt;&lt;br&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lv.Items.Add(li)&lt;br&gt;&lt;br&gt;
&lt;span style="color:#0000FF"&gt;Next&lt;/span&gt;&lt;/p&gt;
&lt;/span&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/5851.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>My.Blogs</title><link>http://blogs.vbcity.com/djjeavons/archive/2006/02/11/5833.aspx</link><pubDate>Sat, 11 Feb 2006 14:14:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2006/02/11/5833.aspx</guid><description>I have finally started to look into Visual Studio 2005 in more detail today and something caught my attention on the start page. It was a link to an &lt;a href="http://msdn.microsoft.com/msdntv/" target="_blank"&gt;MSDN TV&lt;/a&gt; clip that introduces you to the &lt;a href="http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20060126VBasicCM/manifest.xml" target="_blank"&gt;My.Blogs&lt;/a&gt; object that has been created for use with Visual Studio 2005. This object allows you to add blogging capabilities directly into your Windows and ASP.NET projects and also demonstrates how you can extend the My namespace.&lt;p&gt;I have downloaded the &lt;a href="http://msdn.microsoft.com/VBasic/Downloads/Code/MyBlogs/" target="_blank"&gt;sample code&lt;/a&gt; but I had a little trouble installing the Template. However, I was able to easily add a reference to the MyBlogs.dll file and using the following snippet of code (provided by the MSDN documentation) was able to download my current blog entries into a DataGrid.&lt;p&gt;&lt;table width="0" border="0" bgcolor="#E6E6E6" cellspacing="0" cellpadding="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;font color="#0000FF" size=1&gt;Dim&lt;/font&gt;&lt;font size=1&gt; myFeed &lt;/font&gt;&lt;font color="#0000FF" size=1&gt;As&lt;/font&gt;&lt;font size=1&gt; MyBlogs.Feed&lt;br&gt;&lt;br&gt;myFeed = MyBlogs.Feed.Read(&lt;/font&gt;&lt;font color="#800000" size=1&gt;"http://blogs.vbcity.com/djjeavons/Rss.aspx"&lt;/font&gt;&lt;font size=1&gt;)&lt;br&gt;DataGridView1.DataSource = myFeed.Entries&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br&gt;So if anybody is interested in adding blogging capabilities to their application I recommend watching the short introduction, downloading the sample and reading the related articles.&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/5833.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>First Tentative steps in TDD</title><link>http://blogs.vbcity.com/djjeavons/archive/2006/02/08/5826.aspx</link><pubDate>Wed, 08 Feb 2006 20:52:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2006/02/08/5826.aspx</guid><description>Late last year my company provided our IT team with a weeks training in Object Orientated programming and design. Much of the course was taken up with UML and methodologies but the final day was more focused on actual programming concepts (which I enjoyed the most). The tutor was a really nice guy and was happy to answer any questions (I guess at a &amp;pound;1,000 a day, I'd answer anybody's questions). As our IT department is relatively small (4 members) the tutor advised us to follow the &lt;a href="http://en.wikipedia.org/wiki/Scrum_(in_management)" target="_blank"&gt;SCRUM&lt;/a&gt; methodology which is a variation on Extreme Programming (XP) and has thus far helped us be more productive than we have normally managed.&lt;p&gt;

He also mentioned a discipline known as Test Driven Development (TDD) which I had never heard of before and as he explained is the practice of writing tests before writing any code and then making those tests succeed. Now, unless you are aware of this methodology, I would expect the same response as I had, "How can you write a test for something that doesn't exist?". &lt;p&gt;

Well, I have recently been thinking about this principle and done a little research and I can really see the benefits. The basic idea is that you write a test using xUnit (NUnit for VB.NET, JUnit for Java, pyUnit for Python and so on) and run that test. This test will then fail (red bar) as there is no code to test. More likely than not however, the code won't even compile as there is no code for the test to run. So to get around this, you create the object that you are testing and add stubs (empty procedures) in order for your code to compile and then watch it fail. Then you go back to the object and have it return what your test expects it to return (in the first phases, this would be simply hardcoding the values to make the test succeed) and run it again, this time it should succeed (green bar). Then you start to refactor your object so that it starts to look more like a piece of production code rather than a slap happy coder having a laugh! All the time, testing to make sure that each set of changes has not broken the initial test.&lt;p&gt;

Now the thing I really like about this approach is that you can write your initial test that uses a non-existant object and enforce some assumptions on how you would like this non-existant object to expose it's interface. This then gives you a really good outline when it comes to actually creating the object and making those tests succeed. Of even more importance is that when an object has to be changed for whatever reason, you have the tests to rely on that will tell you if you have broken anything by implementing those changes.&lt;p&gt;

So now having done some research on this (links at the bottom for anybody interested), I went ahead and downloaded &lt;a href="http://www.nunit.org/" target="_blank"&gt;NUnit&lt;/a&gt; as I will be using .NET (still trying to learn C# proficiently so may go ahead with that) and also bought a book &lt;a href="http://www.amazon.co.uk/exec/obidos/ASIN/0321146530/qid=1139430668/sr=1-1/ref=sr_1_3_1/026-8191755-5756418" target="_blank"&gt;Test-Driven Development By Example&lt;/a&gt; by Kent Beck. Now I'm armed and ready, I just hope I don't have nightmares about red bars (rather nice dreams about green bars ;))&lt;p&gt;&lt;p&gt;


&lt;b&gt;TDD Links I found of interest&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.agiledata.org/essays/tdd.html" target="_blank"&gt;Introduction to Test Driven Development (TDD)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.testdriven.com/modules/xoopsfaq/index.php?cat_id=5" target="_blank"&gt;Test Driven.Com FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.objectmentor.com/writeUps/TestDrivenDevelopment" target="_blank"&gt;Object Mentor, Inc.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/5826.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>David Jeavons</dc:creator><title>Introducing My Blog</title><link>http://blogs.vbcity.com/djjeavons/archive/2006/02/04/5815.aspx</link><pubDate>Sat, 04 Feb 2006 17:13:00 GMT</pubDate><guid>http://blogs.vbcity.com/djjeavons/archive/2006/02/04/5815.aspx</guid><description>Well, I finally plucked up the courage to give blogging a go, with a little motivation from Ged ;)&lt;p&gt;

So what can you expect from this blog? To be honest, I'm not too sure about that myself. Since I was 18 I have always worked for companies developing Windows software (using VB) but now coming up to the ripe old age of 30 (shudder) I have spent the last year working solely on ASP.NET applications. So I guess, you can expect a number of entries to be related to my struggles/successes with web development. You can also expect a few review type entries as I often evaluate software at my company to assess it's worth.&lt;p&gt;

I will also be upgrading to VS 2005 in the next few months which I am greatly looking forward to so there will no doubt be a few entries there as well. &lt;p&gt;

After that short introduction, I feel I have answered my own question :)&lt;img src ="http://blogs.vbcity.com/djjeavons/aggbug/5815.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>