<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Steve Wellens  : Cache</title><link>http://weblogs.asp.net/stevewellens/archive/tags/Cache/default.aspx</link><description>Tags: Cache</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>A ‘Simple’ Asp.Net Custom Server Control</title><link>http://weblogs.asp.net/stevewellens/archive/2009/12/04/a-simple-asp-net-custom-server-control.aspx</link><pubDate>Sat, 05 Dec 2009 02:00:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7270873</guid><dc:creator>SGWellens</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/stevewellens/rsscomments.aspx?PostID=7270873</wfw:commentRss><comments>http://weblogs.asp.net/stevewellens/archive/2009/12/04/a-simple-asp-net-custom-server-control.aspx#comments</comments><description>&lt;P&gt;A user on the Asp.Net forums, where I moderate, asked how to list a bunch of files in a directory as hyperlinks on a web page so the user could click on them. I thought this was probably an often performed task and decided create a Server Control to encapsulate&amp;nbsp;it. &lt;/P&gt;
&lt;P&gt;Initially, I tried a Web User Control but I wanted to allow setting borders, fonts, background colors, etc. With a Web User Control I would have to create a property for each setting manually. Following the paradigm of, "&lt;EM&gt;The less code you write, the fewer bugs you have&lt;/EM&gt;," I looked for a better way. &lt;/P&gt;
&lt;P&gt;I decided to create my first ever Custom Server Control. I looked at inheriting from a Label control but the Label control has no support for scroll bars. So, I inherited from the Panel control.&amp;nbsp;The final control has all the properties of the Panel control (colors, borders, scrollbar support, etc.)&amp;nbsp; plus a few custom properties I added.&amp;nbsp; Using the Panel control minimized the effort.&lt;/P&gt;
&lt;H2&gt;Part I: The Custom Server Control &lt;/H2&gt;
&lt;P&gt;The initial Server Control was relatively easy. Here's the final code: &lt;/P&gt;
&lt;DIV style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Collections.Generic;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.ComponentModel;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Drawing;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Drawing.Design;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.IO;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Text;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Web;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Web.Caching;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Web.UI;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Web.UI.WebControls;&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;assembly&lt;/SPAN&gt;: &lt;SPAN style="COLOR: #2b91af"&gt;TagPrefix&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"EndWell"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"EW"&lt;/SPAN&gt;)]&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;namespace&lt;/SPAN&gt; EndWell&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;{&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;SPAN style="COLOR: #2b91af"&gt;DefaultProperty&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Text"&lt;/SPAN&gt;)]&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;SPAN style="COLOR: #2b91af"&gt;ToolboxData&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"&amp;lt;{0}:HyperlinkFileList runat=server&amp;gt;&amp;lt;/{0}:HyperlinkFileList&amp;gt;"&lt;/SPAN&gt;)]&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;SPAN style="COLOR: #2b91af"&gt;ToolboxBitmap&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"HyperlinkFileList.ico"&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;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;HyperlinkFileList&lt;/SPAN&gt; : &lt;SPAN style="COLOR: #2b91af"&gt;Panel&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&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: #2b91af"&gt;Bindable&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;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; [&lt;SPAN style="COLOR: #2b91af"&gt;Category&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Files List"&lt;/SPAN&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: #2b91af"&gt;Description&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"The Title of the list of files"&lt;/SPAN&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;string&lt;/SPAN&gt; FilesTitle {&lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&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;SPAN style="COLOR: #2b91af"&gt;Bindable&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;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; [&lt;SPAN style="COLOR: #2b91af"&gt;Category&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Files List"&lt;/SPAN&gt;)]&amp;nbsp;&amp;nbsp;&amp;nbsp;&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: #2b91af"&gt;Description&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"The directory of the files to list:&amp;nbsp; (~/Files/)"&lt;/SPAN&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: green"&gt;// these two built in editors were lacking:&lt;/SPAN&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: green"&gt;//[EditorAttribute(typeof(System.Web.UI.Design.UrlEditor), typeof(UITypeEditor))]&lt;/SPAN&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: green"&gt;//[EditorAttribute(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(UITypeEditor))]&lt;/SPAN&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: #2b91af"&gt;EditorAttribute&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(EndWell.&lt;SPAN style="COLOR: #2b91af"&gt;DualModeFolderEditor&lt;/SPAN&gt;), &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;UITypeEditor&lt;/SPAN&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;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; FilesDirectory { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&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;SPAN style="COLOR: #2b91af"&gt;Bindable&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;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; [&lt;SPAN style="COLOR: #2b91af"&gt;Category&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Files List"&lt;/SPAN&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: #2b91af"&gt;Description&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"The filter for the files to show:&amp;nbsp; (*.*)"&lt;/SPAN&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;string&lt;/SPAN&gt; FilesFilter { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&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;SPAN style="COLOR: #2b91af"&gt;Bindable&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;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; [&lt;SPAN style="COLOR: #2b91af"&gt;Category&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Files List"&lt;/SPAN&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: #2b91af"&gt;Description&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Text to show when there are no files"&lt;/SPAN&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;string&lt;/SPAN&gt; NoFilesText { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&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;SPAN style="COLOR: green"&gt;// ---- Private vars --------------------------&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;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;[] m_FilesArray;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// cached for performance&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;SPAN style="COLOR: green"&gt;// ---- Default constants-------------------&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;SPAN style="COLOR: blue"&gt;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt; DEF_FILES_DIR = &lt;SPAN style="COLOR: #a31515"&gt;"~/xml/"&lt;/SPAN&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;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt; DEF_FILES_FILT = &lt;SPAN style="COLOR: #a31515"&gt;"*.xml"&lt;/SPAN&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;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt; DEF_FILES_TITLE = &lt;SPAN style="COLOR: #a31515"&gt;"XML Files:"&lt;/SPAN&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;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt; DEF_NOFILES_TEXT = &lt;SPAN style="COLOR: #a31515"&gt;"&amp;lt;No Files&amp;gt;"&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;SPAN style="COLOR: green"&gt;// ---- Constructor -------------------------- &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;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; HyperlinkFileList()&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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: green"&gt;// set defaults for our properties&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; FilesDirectory = DEF_FILES_DIR;&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; FilesFilter = DEF_FILES_FILT;&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; FilesTitle = DEF_FILES_TITLE;&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; NoFilesText = DEF_NOFILES_TEXT;&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: green"&gt;// Set defaults for panel properties&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; &lt;SPAN style="COLOR: green"&gt;// I don't like the default width to be full screen&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; &lt;SPAN style="COLOR: green"&gt;// And a border looks better&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; Width = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Unit&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"300px"&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; BorderStyle = &lt;SPAN style="COLOR: #2b91af"&gt;BorderStyle&lt;/SPAN&gt;.Solid;&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; BorderWidth = 1;&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; BorderColor = &lt;SPAN style="COLOR: #2b91af"&gt;Color&lt;/SPAN&gt;.Black;&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: green"&gt;// If height is set, force scroll bars to keep list&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; &lt;SPAN style="COLOR: green"&gt;// from spilling over the panel/div boundaries.&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; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ((Height != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;) &amp;amp;&amp;amp; (ScrollBars == &lt;SPAN style="COLOR: #2b91af"&gt;ScrollBars&lt;/SPAN&gt;.None))&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; ScrollBars = &lt;SPAN style="COLOR: #2b91af"&gt;ScrollBars&lt;/SPAN&gt;.Auto;&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: green"&gt;// Allow multiple controls to be placed horizontally&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; &lt;SPAN style="COLOR: green"&gt;// (normally each div get's its own line)&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &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; Style[&lt;SPAN style="COLOR: #a31515"&gt;"display"&lt;/SPAN&gt;] = &lt;SPAN style="COLOR: #a31515"&gt;"inline-block"&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: green"&gt;// add spacing outside the control&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; Style[&lt;SPAN style="COLOR: #a31515"&gt;"margin"&lt;/SPAN&gt;] = &lt;SPAN style="COLOR: #a31515"&gt;"0.5em"&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: green"&gt;// add space inside the control&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &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; Style[&lt;SPAN style="COLOR: #a31515"&gt;"padding-left"&lt;/SPAN&gt;] = &lt;SPAN style="COLOR: #a31515"&gt;"0.5em"&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; Style[&lt;SPAN style="COLOR: #a31515"&gt;"padding-right"&lt;/SPAN&gt;] = &lt;SPAN style="COLOR: #a31515"&gt;"0.5em"&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; Style[&lt;SPAN style="COLOR: #a31515"&gt;"padding-bottom"&lt;/SPAN&gt;] = &lt;SPAN style="COLOR: #a31515"&gt;"0.5em"&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; &lt;SPAN style="COLOR: green"&gt;// top space usually comes from the title...&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; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;.IsNullOrEmpty(FilesTitle) == &lt;SPAN style="COLOR: blue"&gt;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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Style[&lt;SPAN style="COLOR: #a31515"&gt;"padding-top"&lt;/SPAN&gt;] = &lt;SPAN style="COLOR: #a31515"&gt;"0.5em"&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&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;// ---- RenderContents ----------------------------&lt;/SPAN&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: green"&gt;//&lt;/SPAN&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: green"&gt;// Spit out the HTML&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;SPAN style="COLOR: blue"&gt;protected&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; RenderContents(&lt;SPAN style="COLOR: #2b91af"&gt;HtmlTextWriter&lt;/SPAN&gt; Output)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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: green"&gt;// output the title if one was set&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; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;.IsNullOrEmpty(FilesTitle) == &lt;SPAN style="COLOR: blue"&gt;false&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; {&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; Output.Write(&lt;SPAN style="COLOR: #a31515"&gt;"&amp;lt;h3&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;"&lt;/SPAN&gt;);&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// cosmetic spacing&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; Output.Write(FilesTitle);&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; Output.Write(&lt;SPAN style="COLOR: #a31515"&gt;"&amp;lt;/h3&amp;gt;"&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; }&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; GetFilesArray();&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;if&lt;/SPAN&gt; (m_FilesArray.Length == 0)&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;/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; Output.Write(&lt;SPAN style="COLOR: #2b91af"&gt;HttpUtility&lt;/SPAN&gt;.HtmlEncode(NoFilesText));&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;/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;else&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; {&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: blue"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt; OneFile &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; m_FilesArray)&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;/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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;HyperLink&lt;/SPAN&gt; Link = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;HyperLink&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; Link.NavigateUrl = &lt;SPAN style="COLOR: #2b91af"&gt;Path&lt;/SPAN&gt;.Combine(FilesDirectory, &lt;SPAN style="COLOR: #2b91af"&gt;Path&lt;/SPAN&gt;.GetFileName(OneFile));&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; Link.Text = &lt;SPAN style="COLOR: #2b91af"&gt;Path&lt;/SPAN&gt;.GetFileNameWithoutExtension(OneFile);&amp;nbsp;&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;/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; &amp;nbsp;&amp;nbsp;&amp;nbsp; Link.RenderControl(Output);&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; Output.WriteBreak();&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;/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;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&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;// ---- GetFilesArray -------------------------&lt;/SPAN&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: green"&gt;//&lt;/SPAN&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: green"&gt;// Fill the m_FilesArray with a list of files&lt;/SPAN&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: green"&gt;// either from disk or the cache&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;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; GetFilesArray()&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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: green"&gt;// see if the file list is in the cache.&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; &lt;SPAN style="COLOR: green"&gt;// use directory and filter as unique key&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; m_FilesArray = Page.Cache[FilesDirectory + FilesFilter] &lt;SPAN style="COLOR: blue"&gt;as&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&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;if&lt;/SPAN&gt; (m_FilesArray != &lt;SPAN style="COLOR: blue"&gt;null&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; &lt;SPAN style="COLOR: blue"&gt;return&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: green"&gt;// if no files filter set, use the default one.&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; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;.IsNullOrEmpty(FilesFilter))&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; FilesFilter = DEF_FILES_FILT;&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: green"&gt;// if no files directory set, use the default one.&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; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;.IsNullOrEmpty(FilesDirectory))&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; FilesDirectory = DEF_FILES_DIR;&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: green"&gt;// if a virtual path is detected, map to full path&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; &lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt; FullPath;&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;if&lt;/SPAN&gt; (FilesDirectory.StartsWith(&lt;SPAN style="COLOR: #a31515"&gt;"~"&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; FullPath = Context.Server.MapPath(FilesDirectory);&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;else&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; FullPath = FilesDirectory;&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: green"&gt;// get the files&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; m_FilesArray = &lt;SPAN style="COLOR: #2b91af"&gt;Directory&lt;/SPAN&gt;.GetFiles(FullPath, FilesFilter, &lt;SPAN style="COLOR: #2b91af"&gt;SearchOption&lt;/SPAN&gt;.TopDirectoryOnly);&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: green"&gt;// put the list in the cache so we don't have to read the disk again&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; &lt;SPAN style="COLOR: green"&gt;// use a dependency on the directory being read from for auto refreshing&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; Page.Cache.Insert(FilesDirectory + FilesFilter,&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// unique key&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; m_FilesArray,&amp;nbsp;&amp;nbsp;&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: green"&gt;// list of files to store&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;CacheDependency&lt;/SPAN&gt;(FullPath)); &lt;SPAN style="COLOR: green"&gt;// dependency on directory&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;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P style="BACKGROUND: white"&gt;&lt;!--EndFragment--&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;&lt;SPAN style="COLOR: black"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;&lt;SPAN style="COLOR: black"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="FONT-FAMILY: Courier New; COLOR: black; FONT-SIZE: 10pt"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="TEXT-DECORATION: underline"&gt;&lt;STRONG&gt;Notes: &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The Control Name: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;It's silly to agonize over the name of a control, right? Wrong. Naming a control (or any variable for that matter) is like getting married. You are going to be stuck with it for a very long time and changing it in the future can be extremely painful. Try to get your names right the first time. &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; I called the control: &lt;STRONG&gt;HyperlinkFileList.&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Spillage Problem: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;If height of the control is set and the list of files exceeds the height of the control, the files "spill over" the control's boundaries. &lt;/P&gt;
&lt;P&gt;To fix this, I added this to the control's constructor: &lt;/P&gt;&lt;SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;
&lt;DIV style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;&lt;PRE style="MARGIN: 0px"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; ((Height != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;) &amp;amp;&amp;amp; (ScrollBars == &lt;SPAN style="COLOR: #2b91af"&gt;ScrollBars&lt;/SPAN&gt;.None))&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; ScrollBars = &lt;SPAN style="COLOR: #2b91af"&gt;ScrollBars&lt;/SPAN&gt;.Auto;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;STRONG&gt;CSS Layout: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Since the control is basically a div (the Panel control renders as a div) only one control could be placed on a line. So, I set the "display" attribute to "inline-block". This allows multiple controls to be side-by-side. &lt;/P&gt;&lt;SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;
&lt;DIV style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;&lt;PRE style="MARGIN: 0px"&gt;    Style[&lt;SPAN style="COLOR: #a31515"&gt;"display"&lt;/SPAN&gt;] = &lt;SPAN style="COLOR: #a31515"&gt;"inline-block"&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;!--EndFragment--&gt;&lt;/SPAN&gt;&lt;STRONG&gt;CSS Box Model Tweaks: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;I didn't like the text jammed up against the left edge of the control so I added some CSS padding. I also applied a CSS Margin around the control so it would not butt up against other controls: &lt;/P&gt;&lt;SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;
&lt;DIV style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// add spacing outside the control&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp; Style[&lt;SPAN style="COLOR: #a31515"&gt;"margin"&lt;/SPAN&gt;] = &lt;SPAN style="COLOR: #a31515"&gt;"0.5em"&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; &lt;SPAN style="COLOR: green"&gt;// add space inside the control&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp; Style[&lt;SPAN style="COLOR: #a31515"&gt;"padding-left"&lt;/SPAN&gt;] = &lt;SPAN style="COLOR: #a31515"&gt;"0.5em"&lt;/SPAN&gt;;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;STRONG&gt;State Management: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;During initial testing, I found that each time the control ran, it reread the directory of files. File IO is expensive. I looked at using the integrated Server Control "State" but it used a type of View State and it seemed inefficient to send a list of files to the client twice: Once as the html list and once in View State. &lt;/P&gt;
&lt;P&gt;I looked at using Session State, Application State and the Cache. &lt;/P&gt;
&lt;P&gt;I decided to put the list of files in the Cache object so the lists are shared among sessions .&amp;nbsp; If memory is at a premium, the cached lists are discarded. &lt;/P&gt;
&lt;P&gt;I used the files directory and files filter, concatenated, as the unique key into the cache. This allows multiple controls to be used simultaneously and share file lists.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I initially added a function so the developer could force a re-reading of the files as needed. But the Cache object can use dependencies: Any change in a dependent directory causes the cache to expire. The final code was ridiculously simple:&lt;/P&gt;
&lt;DIV style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;&lt;PRE style="MARGIN: 0px"&gt; &lt;SPAN style="COLOR: green"&gt;// put the list in the cache so we don't have to read the disk again&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt; &lt;SPAN style="COLOR: green"&gt;// use a dependency on the directory being read from for auto refreshing&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt; Page.Cache.Insert(FilesDirectory + FilesFilter,&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// unique key&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; &amp;nbsp; m_FilesArray,&amp;nbsp;&amp;nbsp;&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: green"&gt;// list of files to store&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; &amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;CacheDependency&lt;/SPAN&gt;(FullPath)); &lt;SPAN style="COLOR: green"&gt;// dependency on directory&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;!--EndFragment--&gt;Side Note: Sure, it's just one line of code but it took hours to do the research to decide this was the best way to handle the issue of state management. &lt;EM&gt;Sometimes it takes longer to write less code&lt;/EM&gt;. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Property Editor: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;I grouped all the custom properties of the control under the "Files List" heading so they are all in one place separate from the Panel properties. &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&lt;IMG src="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/Properties.png" mce_src="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/Properties.png"&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Here's the markup for 4 controls on one page: &lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;EW&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;HyperlinkFileList&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="HyperlinkFileList5"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="server"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;BackColor&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="#FFFF66"&lt;/SPAN&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: red"&gt;Height&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="200px"&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;EW&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;HyperlinkFileList&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;EW&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;HyperlinkFileList&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="HyperlinkFileList6"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="server"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;FilesTitle&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="The Same XML Files"&lt;/SPAN&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: red"&gt;Height&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="200px"&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;EW&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;HyperlinkFileList&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;br&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;EW&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;HyperlinkFileList&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="HyperlinkFileList7"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="server"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;BackColor&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="#66FFFF"&lt;/SPAN&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: red"&gt;BorderColor&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="#FF3300"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;BorderWidth&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="3px"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;FilesDirectory&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="C:/Peachw/EndSofi/BAK/"&lt;/SPAN&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: red"&gt;FilesFilter&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="*.Zip"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;FilesTitle&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Whole lotta files!"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;ForeColor&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="#3333CC"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="293px"&lt;/SPAN&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: red"&gt;Height&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="156px"&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;EW&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;HyperlinkFileList&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;EW&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;HyperlinkFileList&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="HyperlinkFileList8"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="server"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;BackColor&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="#66CCFF"&lt;/SPAN&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: red"&gt;Height&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="156px"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="198px"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;FilesDirectory&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="~/Images/"&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;FilesFilter&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="*.jpg"&lt;/SPAN&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: red"&gt;FilesTitle&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Pretty Pictures"&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;EW&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;HyperlinkFileList&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Here's what they look like rendered: &lt;/STRONG&gt;&lt;/P&gt;&lt;IMG src="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/RunningSnapshot.png" mce_src="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/RunningSnapshot.png"&gt; 
&lt;H2&gt;Part II: The Custom Server Control Editor&lt;/H2&gt;&lt;STRONG&gt;Selecting the Files Directory: &lt;/STRONG&gt;
&lt;P&gt;I thought it was amateurish to have the developer type, or paste in, the path to the directory of the files to list so I decided to add a directory browser. Yikes, talk about opening a &lt;A href="http://en.wikipedia.org/wiki/Can_of_worms" mce_href="http://en.wikipedia.org/wiki/Can_of_worms"&gt;can of worms&lt;/A&gt;! &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Developing the Server Control &lt;STRONG&gt;Editor&lt;/STRONG&gt; took longer than developing the actual control. &lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;I thought the control's file directory should be settable in two ways: &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;STRONG&gt;Absolute Path:&lt;/STRONG&gt; C:\PublicData\ImageFiles\ &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;STRONG&gt;Virtual Path&lt;/STRONG&gt;: ~\xmlFiles\ &lt;/P&gt;
&lt;P&gt;I tried two built-in designer browsers&amp;nbsp;by setting attributes on the FilesDirectory property: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;[EditorAttribute(typeof(System.Web.UI.Design.&lt;STRONG&gt;&lt;U&gt;UrlEditor&lt;/U&gt;&lt;/STRONG&gt;), typeof(UITypeEditor))] &lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I rejected the &lt;STRONG&gt;UrlEditor&lt;/STRONG&gt; because it doesn't allow browsing outside the site's home directory. &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;[EditorAttribute(typeof(System.Windows.Forms.Design.&lt;STRONG&gt;&lt;U&gt;FolderNameEditor&lt;/U&gt;&lt;/STRONG&gt;), typeof(UITypeEditor))] &lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I rejected the &lt;STRONG&gt;FolderNameEditor&lt;/STRONG&gt; because there is no provision to select a virtual path. Also, it forces the user to select a file which I did not want. &lt;/P&gt;
&lt;P&gt;To create a Custom Server Control Editor you create a class inheriting from &lt;STRONG&gt;UITypeEditor&lt;/STRONG&gt; and override two functions…one of which launches a DialogBox. &lt;/P&gt;
&lt;P&gt;Here's the code:&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;DIV style="FONT-FAMILY: Courier New; BACKGROUND: white; COLOR: black; FONT-SIZE: 10pt"&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Collections.Generic;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Drawing.Design;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.ComponentModel;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Windows.Forms.Design;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; System.Text;&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; EndWell&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;{&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;DualModeFolderEditor&lt;/SPAN&gt; : &lt;SPAN style="COLOR: #2b91af"&gt;UITypeEditor&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&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;// ---- GetEditStyle --------------------------------&lt;/SPAN&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: green"&gt;//&lt;/SPAN&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: green"&gt;// tell designer what kind of UI we are (Dropdown or Modal DialogBox)&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;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;UITypeEditorEditStyle&lt;/SPAN&gt; GetEditStyle(&lt;SPAN style="COLOR: #2b91af"&gt;ITypeDescriptorContext&lt;/SPAN&gt; context)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;UITypeEditorEditStyle&lt;/SPAN&gt;.Modal;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&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;// ---- EditValue ----------------------------------------&lt;/SPAN&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: green"&gt;//&lt;/SPAN&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: green"&gt;// Called by IDE designer when user clicks the ... button&lt;/SPAN&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: green"&gt;// A DialogBox is launched&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;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; EditValue(&lt;SPAN style="COLOR: #2b91af"&gt;ITypeDescriptorContext&lt;/SPAN&gt; Context,&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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: #2b91af"&gt;IServiceProvider&lt;/SPAN&gt; Provider,&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; Value)&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; &amp;nbsp;&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: #2b91af"&gt;IWindowsFormsEditorService&lt;/SPAN&gt; EditorService = &lt;SPAN style="COLOR: blue"&gt;null&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; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (Provider != &lt;SPAN style="COLOR: blue"&gt;null&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; {&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; EditorService = (&lt;SPAN style="COLOR: #2b91af"&gt;IWindowsFormsEditorService&lt;/SPAN&gt;)Provider.GetService(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;IWindowsFormsEditorService&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; }&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;if&lt;/SPAN&gt; (EditorService != &lt;SPAN style="COLOR: blue"&gt;null&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; {&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: green"&gt;// launch the dialog box&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; &lt;SPAN style="COLOR: #2b91af"&gt;DuaModeFolderEditorForm&lt;/SPAN&gt; Editor = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;DuaModeFolderEditorForm&lt;/SPAN&gt;(Value.ToString(), Context);&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; EditorService.ShowDialog(Editor);&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: blue"&gt;return&lt;/SPAN&gt; Editor.m_Value;&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;/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;else&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; {&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;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; Value;&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;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;} &amp;nbsp;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Here's what the editor's DialogBox looks like: &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;IMG src="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/DualModePathEditor.png" mce_src="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/DualModePathEditor.png"&gt;&lt;/P&gt;
&lt;P&gt;I'm not going to show the DialogBox code since it's a bit long and involved.&amp;nbsp;&amp;nbsp; Note: You can &lt;A href="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/HyperlinkFileList.zip" mce_href="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/HyperlinkFileList.zip"&gt;download&lt;/A&gt; the project if you wish. There was a lot of trial and error in developing it because the documentation is lacking. But there were a few things of interest… &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Directory Separators (Slashes): &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The &lt;STRONG&gt;GetProjectItemFromUrl&lt;/STRONG&gt; function did not work when a backslash was used like this: "\~". It did work with a forward slash like this: "/~". &lt;/P&gt;
&lt;P&gt;So, I made sure all the directory separators used forward slashes. BUT, the directories returned from the Directory browser uses backslashes. So I also 'fixed' those for consistency…sigh &lt;SPAN style="FONT-FAMILY: Wingdings"&gt;L&lt;/SPAN&gt;.&amp;nbsp;&amp;nbsp; It made the code a bit messier than I prefer but there really was no other choice. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Server Control Development Tip: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Once the control is on a page, you can automatically update the DLL in the bin directory by right clicking the control and selecting "Refresh". This worked most of the time. &lt;/P&gt;
&lt;P&gt;Other times I had to delete the control from the bin directory and then re-add it to the project by dropping it on a web page to get the latest version. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Debugging the Editor: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Debugging the control was easy. Debugging the control editor was hard because it runs in Visual Studio. I added this line at various places in the editor code: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;System.Diagnostics.Debugger.Break();&lt;/STRONG&gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;When the breakpoint is hit, you get this delightful screen: &lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG style="WIDTH: 504px; HEIGHT: 259px" src="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/UserBreakpoint.png" width=504 height=259 mce_src="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/UserBreakpoint.png"&gt;&lt;/P&gt;
&lt;P&gt;Click &lt;STRONG&gt;"Debug the program"&lt;/STRONG&gt; and a new instance of Visual Studio is launched so you can debug the control editor. However, the original running Visual Studio is locked-up (at least on my box it was) and had to be ungracefully terminated. &lt;/P&gt;
&lt;P&gt;Since the documentation on Custom Server Control editors is somewhat lacking, it was invaluable to be able to poke around and see what was being passed in and what was happening. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Possible Enhancements: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;As with most tasks like this, you can get carried away and start adding features '&lt;A href="http://en.wiktionary.org/wiki/until_the_cows_come_home" mce_href="http://en.wiktionary.org/wiki/until_the_cows_come_home"&gt;until the cows come home&lt;/A&gt;': &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Make the title font settable (size, color, background color...) &lt;/LI&gt;
&lt;LI&gt;Put the title in one fixed div and the list of files in another resizable or scrollable div. &lt;/LI&gt;
&lt;LI&gt;Add a Boolean field to optionally display the file extensions in the links. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Conclusion: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;I learned a lot building the control mostly because I got stuck a few times. But, now I have a working template for any future Server Controls that can be contained inside a Panel Control…and so do you. &lt;/P&gt;
&lt;P&gt;The full project, including debug and release build dlls can be downloaded &lt;A href="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/HyperlinkFileList.zip" mce_href="http://weblogs.asp.net/blogs/stevewellens/2009_Dec/HyperlinkFileList.zip"&gt;here&lt;/A&gt;. It's targeted for .Net 3.5 but can probably be rebuilt for other versions since it's not using any special features. &lt;/P&gt;
&lt;P&gt;I hope someone finds this useful. &lt;/P&gt;
&lt;P&gt;Steve Wellens&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7270873" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/stevewellens/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/stevewellens/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/stevewellens/archive/tags/Cache/default.aspx">Cache</category><category domain="http://weblogs.asp.net/stevewellens/archive/tags/Server+Control/default.aspx">Server Control</category><category domain="http://weblogs.asp.net/stevewellens/archive/tags/HyperlinkFileList/default.aspx">HyperlinkFileList</category></item><item><title>Rock the Cache Bar, Rock the Cache Bar</title><link>http://weblogs.asp.net/stevewellens/archive/2009/02/27/rock-the-cache-bar-rock-the-cache-bar.aspx</link><pubDate>Fri, 27 Feb 2009 23:02:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6931351</guid><dc:creator>SGWellens</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/stevewellens/rsscomments.aspx?PostID=6931351</wfw:commentRss><comments>http://weblogs.asp.net/stevewellens/archive/2009/02/27/rock-the-cache-bar-rock-the-cache-bar.aspx#comments</comments><description>&lt;P&gt;It's possible you may develop dozens of web sites without ever doing any data caching. However, if you are trying to increase performance, data caching can be a key tool. The Asp.Net Cache object is remarkably easy to use, but it has many settings which makes it extremely powerful. &lt;/P&gt;
&lt;P&gt;The only way to learn and get a good understanding of the Cache object's features is to experiment. To keep my experiment from being too tedious, I use short times. &lt;/P&gt;
&lt;P&gt;In the Web.Config file, I set the Session timeout to be 2 minutes: &lt;/P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-SIZE: 9pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;system.web&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;sessionState&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;timeout&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;2&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;sessionState&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;system.web&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P style="BACKGROUND: white"&gt;&lt;!--EndFragment--&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;Stepping through the code with the debugger will interfere with timings...so trace statements are used. In order to get timestamps in the trace statements, I used a function in a static utility class I have: &amp;nbsp;ODS stands for Output Debug String: &lt;/P&gt;
&lt;DIV style="FONT-SIZE: 9pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;MiscUtilities&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;{ &lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; ---- ODS ---------------------------------------&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Output Debug String with time stamp.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/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;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ODS(&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; Msg)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&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: #2b91af"&gt;String&lt;/SPAN&gt; Out = &lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;.Format(&lt;SPAN style="COLOR: #a31515"&gt;"{0}&amp;nbsp; {1}"&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; &lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now.ToString(&lt;SPAN style="COLOR: #a31515"&gt;"hh:mm:ss.ff"&lt;/SPAN&gt;), Msg);&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; System.Diagnostics.&lt;SPAN style="COLOR: #2b91af"&gt;Debug&lt;/SPAN&gt;.WriteLine(Out);&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;!--EndFragment--&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;I was interested in how the Cache interacted with normal page events. In the Global.asax file, I trace the events with my utility function: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-SIZE: 9pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;@&lt;/SPAN&gt; &lt;SPAN style="COLOR: #a31515"&gt;Application&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND: #ffee62"&gt;%&amp;gt;&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;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;script&lt;/SPAN&gt; &lt;SPAN style="COLOR: red"&gt;RunAt&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="server"&amp;gt;&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;void&lt;/SPAN&gt; Application_Start(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; sender, &lt;SPAN style="COLOR: #2b91af"&gt;EventArgs&lt;/SPAN&gt; e)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&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: #2b91af"&gt;MiscUtilities&lt;/SPAN&gt;.ODS(&lt;SPAN style="COLOR: #a31515"&gt;"****ApplicationStart"&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; &lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Application_BeginRequest(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; sender, &lt;SPAN style="COLOR: #2b91af"&gt;EventArgs&lt;/SPAN&gt; e) &lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&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: #2b91af"&gt;MiscUtilities&lt;/SPAN&gt;.ODS(&lt;SPAN style="COLOR: #a31515"&gt;"Application_BeginRequest"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Application_EndRequest(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; sender, &lt;SPAN style="COLOR: #2b91af"&gt;EventArgs&lt;/SPAN&gt; e)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&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: #2b91af"&gt;MiscUtilities&lt;/SPAN&gt;.ODS(&lt;SPAN style="COLOR: #a31515"&gt;"Application_EndRequest"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Session_Start(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; sender, &lt;SPAN style="COLOR: #2b91af"&gt;EventArgs&lt;/SPAN&gt; e)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&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: #2b91af"&gt;MiscUtilities&lt;/SPAN&gt;.ODS(&lt;SPAN style="COLOR: #a31515"&gt;"Session_Start"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Application_End(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; sender, &lt;SPAN style="COLOR: #2b91af"&gt;EventArgs&lt;/SPAN&gt; e)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&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: #2b91af"&gt;MiscUtilities&lt;/SPAN&gt;.ODS(&lt;SPAN style="COLOR: #a31515"&gt;"Application_End"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Application_Error(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; sender, &lt;SPAN style="COLOR: #2b91af"&gt;EventArgs&lt;/SPAN&gt; e)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&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: #2b91af"&gt;MiscUtilities&lt;/SPAN&gt;.ODS(&lt;SPAN style="COLOR: #a31515"&gt;"Application_Error "&lt;/SPAN&gt; + Server.GetLastError().Message);&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Session_End(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; sender, &lt;SPAN style="COLOR: #2b91af"&gt;EventArgs&lt;/SPAN&gt; e)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&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: #2b91af"&gt;MiscUtilities&lt;/SPAN&gt;.ODS(&lt;SPAN style="COLOR: #a31515"&gt;"Session_End"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;script&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;&lt;!--EndFragment--&gt;
&lt;P&gt;To explain the test we need to know what &lt;STRONG&gt;Sliding Expiration&lt;/STRONG&gt; is. When you tell a Cache to use Sliding Expiration and give it a &lt;EM&gt;TimeSpan&lt;/EM&gt; of 5 minutes, it may never time out. Every time the cache object is accessed, the timer is reset. This is great, if a cached object is used a lot, it will remain cached. Rarely used cached objects will be released. &lt;/P&gt;
&lt;P&gt;If we use &lt;STRONG&gt;Absolute Expiration&lt;/STRONG&gt;, then we use a &lt;EM&gt;DateTime&lt;/EM&gt; to supply a specific time to release the cached object. If you know a database will be updated at 1:00 AM, you may want to have a cached item released and reset at 2:00 AM. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Side Note:&lt;/STRONG&gt; You can also set a Cached object to expired when a file has changed. I didn't test this but I can see how it would be useful to allow nontechnical people to update the text content on a web page. &lt;/P&gt;
&lt;P&gt;One of the most intriguing features of the Cache object is that you can have a function called when a Cache object expires. This is the feature I was most interested in. &lt;/P&gt;
&lt;P&gt;Since the cache going to be set in two places, I created a function so all the settings would be in one place. For this test I used a string, but any serializable object can be placed in the Cache. I set the Cached object to expire 5 seconds in the future.&amp;nbsp;A delegate is created for the callback function. &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-SIZE: 9pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; InsertToCache(&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt; Key, &lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt; Item)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;{&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Item = Item + &lt;SPAN style="COLOR: #a31515"&gt;"+"&lt;/SPAN&gt;;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// append a char to the cached object&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: #2b91af"&gt;MiscUtilities&lt;/SPAN&gt;.ODS(&lt;SPAN style="COLOR: #a31515"&gt;"Cache Inserted:&amp;nbsp; "&lt;/SPAN&gt; + Key + &lt;SPAN style="COLOR: #a31515"&gt;"&amp;nbsp; "&lt;/SPAN&gt; + Item);&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: #2b91af"&gt;CacheItemRemovedCallback&lt;/SPAN&gt; RemoveCallBack = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;CacheItemRemovedCallback&lt;/SPAN&gt;(onCacheRemove);&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; Cache.Insert(Key, &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;&amp;nbsp; Item, &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;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;null&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;&amp;nbsp; System.&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now.AddSeconds(5),&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;&amp;nbsp; System.Web.Caching.&lt;SPAN style="COLOR: #2b91af"&gt;Cache&lt;/SPAN&gt;.NoSlidingExpiration,&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;&amp;nbsp; System.Web.Caching.&lt;SPAN style="COLOR: #2b91af"&gt;CacheItemPriority&lt;/SPAN&gt;.Default,&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;&amp;nbsp; RemoveCallBack);&amp;nbsp;&amp;nbsp; &lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;}&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;!--EndFragment--&gt;I set the callback function to re-insert the item into the Cache: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-SIZE: 9pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: green"&gt;// ---- onCacheRemove --------------------&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: green"&gt;//&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: green"&gt;// Fires when an item is removed from the cache&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;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; onCacheRemove(&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; Key, &lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; Item, &lt;SPAN style="COLOR: #2b91af"&gt;CacheItemRemovedReason&lt;/SPAN&gt; Reason)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;{&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;MiscUtilities&lt;/SPAN&gt;.ODS(&lt;SPAN style="COLOR: #a31515"&gt;"onCacheRemove: "&lt;/SPAN&gt; + Key + &lt;SPAN style="COLOR: #a31515"&gt;"&amp;nbsp; "&lt;/SPAN&gt; + Reason.ToString());&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: green"&gt;// re-insert the item back into the cache&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; InsertToCache(Key, Item.ToString());&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;}&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;&lt;!--EndFragment--&gt;
&lt;P&gt;And finally, here is how I kicked it of: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-SIZE: 9pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;protected&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Page_Load(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; sender, &lt;SPAN style="COLOR: #2b91af"&gt;EventArgs&lt;/SPAN&gt; e)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;{&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (!IsPostBack)&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; InsertToCache(&lt;SPAN style="COLOR: #a31515"&gt;"Key"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"+"&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; &lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;}&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;&lt;!--EndFragment--&gt;
&lt;P&gt;Here is the output: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;04:42:30.93&amp;nbsp; ****ApplicationStart&lt;BR&gt;04:42:30.94&amp;nbsp; Application_BeginRequest&lt;BR&gt;04:42:32.40&amp;nbsp; Session_Start&lt;BR&gt;04:42:32.46&amp;nbsp; Cache Inserted:&amp;nbsp; Key&amp;nbsp; ++&lt;BR&gt;04:42:32.64&amp;nbsp; Application_EndRequest&lt;BR&gt;04:42:32.67&amp;nbsp; Application_BeginRequest&lt;BR&gt;04:42:32.68&amp;nbsp; Application_EndRequest&lt;BR&gt;04:42:40.01&amp;nbsp; onCacheRemove: Key&amp;nbsp; Expired&lt;BR&gt;04:42:40.01&amp;nbsp; Cache Inserted:&amp;nbsp; Key&amp;nbsp; +++&lt;BR&gt;04:43:00.01&amp;nbsp; onCacheRemove: Key&amp;nbsp; Expired&lt;BR&gt;04:43:00.01&amp;nbsp; Cache Inserted:&amp;nbsp; Key&amp;nbsp; ++++&lt;BR&gt;04:43:20.01&amp;nbsp; onCacheRemove: Key&amp;nbsp; Expired&lt;BR&gt;04:43:20.01&amp;nbsp; Cache Inserted:&amp;nbsp; Key&amp;nbsp; +++++&lt;BR&gt;04:43:40.01&amp;nbsp; onCacheRemove: Key&amp;nbsp; Expired&lt;BR&gt;04:43:40.01&amp;nbsp; Cache Inserted:&amp;nbsp; Key&amp;nbsp; ++++++&lt;BR&gt;04:44:00.01&amp;nbsp; onCacheRemove: Key&amp;nbsp; Expired&lt;BR&gt;04:44:00.01&amp;nbsp; Cache Inserted:&amp;nbsp; Key&amp;nbsp; +++++++&lt;BR&gt;04:44:20.01&amp;nbsp; onCacheRemove: Key&amp;nbsp; Expired&lt;BR&gt;04:44:20.01&amp;nbsp; Cache Inserted:&amp;nbsp; Key&amp;nbsp; ++++++++&lt;BR&gt;04:44:40.01&amp;nbsp; onCacheRemove: Key&amp;nbsp; Expired&lt;BR&gt;04:44:40.01&amp;nbsp; Cache Inserted:&amp;nbsp; Key&amp;nbsp; +++++++++&lt;BR&gt;&lt;STRONG&gt;04:44:40.01&amp;nbsp; Session_End&lt;/STRONG&gt;&lt;BR&gt;04:45:00.01&amp;nbsp; onCacheRemove: Key&amp;nbsp; Expired&lt;BR&gt;04:45:00.01&amp;nbsp; Cache Inserted:&amp;nbsp; Key&amp;nbsp; ++++++++++&lt;BR&gt;04:45:20.01&amp;nbsp; onCacheRemove: Key&amp;nbsp; Expired&lt;BR&gt;04:45:20.01&amp;nbsp; Cache Inserted:&amp;nbsp; Key&amp;nbsp; +++++++++++&lt;BR&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN style="TEXT-DECORATION: underline"&gt;&lt;STRONG&gt;Interesting Note 1: &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Cached objects are independent of sessions. After the session that created the Cache object expired, the object lived on. Cached objects are shared across sessions and last for the duration of the application. If you have one hundred simultaneous users and they all need a static customer list from the database, you can save a boatload of database calls by caching the list. &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="TEXT-DECORATION: underline"&gt;&lt;STRONG&gt;Interesting Note 2: &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;I set the expiration date to be 5 seconds in the future but the Cached object expired every 20 seconds. What's that all about? I experimented with different time values: &lt;/P&gt;
&lt;DIV style="MARGIN-LEFT: 36pt"&gt;
&lt;TABLE class="" style="BORDER-COLLAPSE: collapse" border=0&gt;
&lt;COLGROUP&gt;
&lt;COL style="WIDTH: 153px"&gt;
&lt;COL style="WIDTH: 203px"&gt;&lt;/COLGROUP&gt;
&lt;TBODY vAlign=top&gt;
&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: black 0.5pt solid; PADDING-LEFT: 7px; BORDER-LEFT: black 0.5pt solid; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;Time to Expire (secs)&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: black 0.5pt solid; PADDING-LEFT: 7px; BORDER-LEFT: medium none; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;Time Actually Expired (secs)&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: black 0.5pt solid; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;3&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: medium none; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;20&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: black 0.5pt solid; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;5&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: medium none; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;20&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: black 0.5pt solid; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;20&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: medium none; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;40&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: black 0.5pt solid; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;30&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: medium none; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;40&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: black 0.5pt solid; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;50&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: medium none; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;60&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: black 0.5pt solid; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;70&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" style="BORDER-RIGHT: black 0.5pt solid; PADDING-RIGHT: 7px; BORDER-TOP: medium none; PADDING-LEFT: 7px; BORDER-LEFT: medium none; BORDER-BOTTOM: black 0.5pt solid"&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;80&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;P&gt;Ahhh, there must be a thread that checks every 20 seconds for expired objects. &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="TEXT-DECORATION: underline"&gt;&lt;STRONG&gt;Interesting Note 3: &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Two of the parameters of the Cache Insert function are &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;DateTime &lt;STRONG&gt;absoluteExpiration&lt;/STRONG&gt;, &lt;BR&gt;TimeSpan &lt;STRONG&gt;slidingExpiration&lt;/STRONG&gt;&lt;BR&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;They are used like this: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-SIZE: 9pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;PRE style="MARGIN: 0px"&gt;Cache.Insert(Key, &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; Item, &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; &lt;SPAN style="COLOR: blue"&gt;null&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; System.&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now.AddSeconds(5),&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; System.Web.Caching.&lt;SPAN style="COLOR: #2b91af"&gt;Cache&lt;/SPAN&gt;.&lt;U&gt;&lt;STRONG&gt;NoSlidingExpiration&lt;/STRONG&gt;,&lt;/U&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; System.Web.Caching.&lt;SPAN style="COLOR: #2b91af"&gt;CacheItemPriority&lt;/SPAN&gt;.Default,&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; RemoveCallBack);&amp;nbsp;&amp;nbsp; &lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;&lt;!--EndFragment--&gt;
&lt;P&gt;Or like this: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-SIZE: 9pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;PRE style="MARGIN: 0px"&gt;Cache.Insert(Key,&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; Item,&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; &lt;SPAN style="COLOR: blue"&gt;null&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; System.Web.Caching.&lt;SPAN style="COLOR: #2b91af"&gt;Cache&lt;/SPAN&gt;.&lt;STRONG&gt;&lt;U&gt;NoAbsoluteExpiration&lt;/U&gt;&lt;/STRONG&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; &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;TimeSpan&lt;/SPAN&gt;(0, 0, 30),&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; System.Web.Caching.&lt;SPAN style="COLOR: #2b91af"&gt;CacheItemPriority&lt;/SPAN&gt;.Default,&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; RemoveCallBack);&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;&lt;!--EndFragment--&gt;
&lt;P&gt;The person who designed this used a trick. He created dummy variables with the correct type and gave them "Flag Names". &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;DIV style="FONT-SIZE: 9pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;PRE style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;namespace&lt;/SPAN&gt; System.Web.Caching&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;{&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;sealed&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Cache&lt;/SPAN&gt; : &lt;SPAN style="COLOR: #2b91af"&gt;IEnumerable&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&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;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;readonly&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt; NoAbsoluteExpiration;&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;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;readonly&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;TimeSpan&lt;/SPAN&gt; NoSlidingExpiration;&lt;/PRE&gt;&lt;/DIV&gt;&lt;!--EndFragment--&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This allows the "flags" to be passed where a DateTime or TimeSpan is expected. While I admire the cleverness, I would have used an enum. &lt;/P&gt;
&lt;P&gt;I hope someone finds this useful, or at least interesting. &lt;/P&gt;
&lt;P&gt;Steve Wellens&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6931351" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/stevewellens/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/stevewellens/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/stevewellens/archive/tags/Steve+Wellens/default.aspx">Steve Wellens</category><category domain="http://weblogs.asp.net/stevewellens/archive/tags/State/default.aspx">State</category><category domain="http://weblogs.asp.net/stevewellens/archive/tags/Sessions/default.aspx">Sessions</category><category domain="http://weblogs.asp.net/stevewellens/archive/tags/Cache/default.aspx">Cache</category></item></channel></rss>