<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fresh Click Media &#187; ASP.NET</title>
	<atom:link href="http://www.freshclickmedia.com/blog/category/aspnet/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.freshclickmedia.com</link>
	<description></description>
	<lastBuildDate>Mon, 23 Aug 2010 20:00:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>5 things you may not know about ASP.NET</title>
		<link>http://www.freshclickmedia.com/blog/2009/03/5-things-you-may-not-know-about-aspnet/</link>
		<comments>http://www.freshclickmedia.com/blog/2009/03/5-things-you-may-not-know-about-aspnet/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 12:17:55 +0000</pubDate>
		<dc:creator>Shane</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.freshclickmedia.com/?p=138</guid>
		<description><![CDATA[Since its release in early 2002, Microsoft's ASP.NET platform has gone from strength to strength.  Despite its strong uptake from Microsoft-centric software houses, there may be a few people who have hesitated in adopting ASP.NET for their web development platform.  Here I present some things you might not know about ASP.NET.  Perhaps it'll encourage you to take a look at it.

<h3>Cost</h3>
There once was a time when the standard IDE for developing ASP.NET apps, Visual Studio, was prohibitively expensive for the average Joe.  In late 2007, Microsoft released its first versions of 'Express' software, aimed at students and hobbyists.  Though Express incarnations have fewer features than their full version cousins, they do offer the possibility of exploring ASP.NET.  The Microsoft website offers a <a href="http://www.microsoft.com/express/vwd/">download page for Visual Web Developer 2008 Express Edition</a>. An express version of SQL Server is also available, and can be downloaded from the <a href="http://www.microsoft.com/express/sql/">SQL Server 2008 download page</a>.

<h3><abbr title="Model View Controller">MVC</abbr> Support</h3>
The MVC pattern is an established and well-recognised way of building web applications, and is familiar to <abbr title="Ruby on Rails">RoR</abbr>, Java and PHP developers.  For many years, MVC was not available as a standard approach to developing ASP.NET websites, but Microsoft has recognised the deficiency and have (at the time of writing) released version 1.0 Release Candidate of ASP.NET MVC.  The release has had a mixed response from the ASP.NET community, many of whom are used to the traditional code-behind model.  Despite the inevitable squabbles as to which way is best, many have welcomed the MVC approach for its separation of concerns and finer control over JavaScript and markup.  To find out more about the release candidate, head over to <a href="http://weblogs.asp.net/scottgu/archive/2009/01/27/asp-net-mvc-1-0-release-candidate-now-available.aspx">Scott Guthrie's blog post</a>.

<h3>Learning Resources</h3>  
A big advantage for anybody learning a new technology is the wealth of learning material that is available.  Although you can rely on a large number of books, the <a href="http://www.asp.net/learn">ASP.NET learn</a> website contains many videos on both traditional and MVC ASP.NET as well as data access.

<h3>Intrinsic jQuery Support</h3>
The lightweight open source JavaScript library that's taken the web by storm is now fully supported by Microsoft.  As well as <a href="http://weblogs.asp.net/scottgu/archive/2008/11/21/jquery-intellisense-in-vs-2008.aspx">full intellisense support in Visual Studio</a>, Microsoft will be using the library as-is, without forking or changing the code from the main jQuery branch.  What's more, Microsoft will be using jQuery as a basis for future ASP.NET and ASP.NET AJAX features.  I feel this counters the argument of Microsoft not supporting open-source software.

<h3>Career Prospects</h3>
Microsoft's ubiquity means that learning ASP.NET and supporting technologies will do no harm to your career prospects.  <a href="http://www.cwjobs.co.uk/Content/PermanentDeveloperDemand.html">.NET skills are ranked as some of the most in-demand in the UK</a>.  ]]></description>
			<content:encoded><![CDATA[<p>Since its release in early 2002, Microsoft&#8217;s ASP.NET platform has gone from strength to strength.  Despite its strong uptake from Microsoft-centric software houses, there may be a few people who have hesitated in adopting ASP.NET for their web development platform.  Here I present some things you might not know about ASP.NET.  Perhaps it&#8217;ll encourage you to take a look at it.</p>
<h3>Cost</h3>
<p>There once was a time when the standard IDE for developing ASP.NET apps, Visual Studio, was prohibitively expensive for the average Joe.  In late 2007, Microsoft released its first versions of &#8216;Express&#8217; software, aimed at students and hobbyists.  Though Express incarnations have fewer features than their full version cousins, they do offer the possibility of exploring ASP.NET.  The Microsoft website offers a <a href="http://www.microsoft.com/express/vwd/">download page for Visual Web Developer 2008 Express Edition</a>. An express version of SQL Server is also available, and can be downloaded from the <a href="http://www.microsoft.com/express/sql/">SQL Server 2008 download page</a>.</p>
<h3><abbr title="Model View Controller">MVC</abbr> Support</h3>
<p>The MVC pattern is an established and well-recognised way of building web applications, and is familiar to <abbr title="Ruby on Rails">RoR</abbr>, Java and PHP developers.  For many years, MVC was not available as a standard approach to developing ASP.NET websites, but Microsoft has recognised the deficiency and have (at the time of writing) released version 1.0 Release Candidate of ASP.NET MVC.  The release has had a mixed response from the ASP.NET community, many of whom are used to the traditional code-behind model.  Despite the inevitable squabbles as to which way is best, many have welcomed the MVC approach for its separation of concerns and finer control over JavaScript and markup.  To find out more about the release candidate, head over to <a href="http://weblogs.asp.net/scottgu/archive/2009/01/27/asp-net-mvc-1-0-release-candidate-now-available.aspx">Scott Guthrie&#8217;s blog post</a>.</p>
<h3>Learning Resources</h3>
<p>A big advantage for anybody learning a new technology is the wealth of learning material that is available.  Although you can rely on a large number of books, the <a href="http://www.asp.net/learn">ASP.NET learn</a> website contains many videos on both traditional and MVC ASP.NET as well as data access.</p>
<h3>Intrinsic jQuery Support</h3>
<p>The lightweight open source JavaScript library that&#8217;s taken the web by storm is now fully supported by Microsoft.  As well as <a href="http://weblogs.asp.net/scottgu/archive/2008/11/21/jquery-intellisense-in-vs-2008.aspx">full intellisense support in Visual Studio</a>, Microsoft will be using the library as-is, without forking or changing the code from the main jQuery branch.  What&#8217;s more, Microsoft will be using jQuery as a basis for future ASP.NET and ASP.NET AJAX features.  I feel this counters the argument of Microsoft not supporting open-source software.</p>
<h3>Career Prospects</h3>
<p>Microsoft&#8217;s ubiquity means that learning ASP.NET and supporting technologies will do no harm to your career prospects.  <a href="http://www.cwjobs.co.uk/Content/PermanentDeveloperDemand.html">.NET skills are ranked as some of the most in-demand in the UK</a>.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.freshclickmedia.com/blog/2009/03/5-things-you-may-not-know-about-aspnet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gravatar Control Update</title>
		<link>http://www.freshclickmedia.com/blog/2008/03/gravatar-control-update/</link>
		<comments>http://www.freshclickmedia.com/blog/2008/03/gravatar-control-update/#comments</comments>
		<pubDate>Tue, 18 Mar 2008 19:08:58 +0000</pubDate>
		<dc:creator>Shane</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.freshclickmedia.com/blog/2008/03/gravatar-control-update/</guid>
		<description><![CDATA[The guys over at <a href="http://www.gravatar.com">Gravatar.com</a> have been hard at work <a href="http://blog.gravatar.com/2008/03/14/big-changes-afoot/">updating their service</a>, and I've updated the <a href="http://www.freshclickmedia.com/blog/2008/02/gravatar-aspnet-control/">ASP.NET control I developed</a> to reflect the changes.]]></description>
			<content:encoded><![CDATA[<h3>Update &#8211; 12 June 2008</h3>
<p>An updated version of this post, containing full source for the control and explanation is available <a href="http://www.freshclickmedia.com/blog/2008/06/aspnet-gravatar-control-update-full-source-included/">here</a>.</p>
<h3>Original Post</h3>
<p>The guys over at <a href="http://www.gravatar.com">Gravatar.com</a> have been hard at work <a href="http://blog.gravatar.com/2008/03/14/big-changes-afoot/">updating their service</a>, and I&#8217;ve updated the <a href="http://www.freshclickmedia.com/blog/2008/02/gravatar-aspnet-control/">ASP.NET control I developed</a> to reflect the changes.</p>
<p>The maximum size of Gravatars has now been increased from 80 to 512, so there&#8217;s a code change in the Render method:</p>
<pre class="code">
// if the size property has been specified, and in the range
// 1..512:
try
{
    // if it's not in the allowed range, throw an exception:
    if (Size < 1 || Size > 512)
        throw new ArgumentOutOfRangeException();
}
catch
{
    Size = 80;
}
</pre>
<p>So, a default of 80 will still be used if the value specified is not within the 1 to 512 range, or it is not specified, but allows for a larger size.</p>
<p>The avatar.php URL serving the images <a href="http://blog.gravatar.com/2008/03/14/big-changes-afoot/">now supports abbreviation</a>, but the code in the control has not been changed.</p>
<p><img src="http://farm3.static.flickr.com/2303/2343923834_a85fa1e873_o.gif" alt="Design time view of the control" width="505" height="429" /></p>
<p>The image shows the Design time view of the control, with the width set at the default value of 80.  I&#8217;ve checked the control at 512 pixels, but my Gravatar doesn&#8217;t look too good expanded out to that size, so I&#8217;ve decided to stick at size 80 for the screenshot!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freshclickmedia.com/blog/2008/03/gravatar-control-update/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Gravatar ASP.NET Control</title>
		<link>http://www.freshclickmedia.com/blog/2008/02/gravatar-aspnet-control/</link>
		<comments>http://www.freshclickmedia.com/blog/2008/02/gravatar-aspnet-control/#comments</comments>
		<pubDate>Fri, 22 Feb 2008 20:59:08 +0000</pubDate>
		<dc:creator>Shane</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.freshclickmedia.com/blog/2008/02/gravatar-aspnet-control/</guid>
		<description><![CDATA[I just got myself a freshclickmedia.com Gravatar over at <a href="http://site.gravatar.com/" title="Get your own Gravatar">gravatar.com</a>.  A Gravatar is a little avatar associated with an email address, and quite a few blogs use them to decorate post comments.  Signing up is easy - all you need to do is supply an email address, and image, and give your image a content rating.

The source of the gravatar image tag points to gravatar.com's image generator and includes an MD5 hash of the email address to prevent email harvesting.  A 'max rating' parameter prevents the display of unsavoury content.

There are a wide number of blogging gravatar plugins, so I decided to write an ASP.NET custom control to do the job.  Here I present the control and its features.
]]></description>
			<content:encoded><![CDATA[<h3>Update &#8211; 12 June 2008</h3>
<p>An updated version of this post, containing full source for the control and explanation is available <a href="http://www.freshclickmedia.com/blog/2008/06/aspnet-gravatar-control-update-full-source-included/">here</a>.</p>
<h3>Original Post</h3>
<p>I just got myself a freshclickmedia.com Gravatar over at <a href="http://site.gravatar.com/" title="Get your own Gravatar">gravatar.com</a>.  A Gravatar is a little avatar associated with an email address, and quite a few blogs use them to decorate post comments.  Signing up is easy &#8211; all you need to do is supply an email address, and image, and give your image a content rating.</p>
<p>The source of the gravatar image tag points to gravatar.com&#8217;s image generator and includes an MD5 hash of the email address to prevent email harvesting.  A &#8216;max rating&#8217; parameter prevents the display of unsavoury content.</p>
<p>There are a wide number of blogging gravatar plugins, so I decided to write an ASP.NET custom control to do the job.  Here I present the control and its features.</p>
<p><span id="more-80"></span></p>
<h3>Using the Control</h3>
<p>To get up and running, the control requires an email address:</p>
<pre class="code">
&lt;fcm:Gravatar ID=&apos;Gravatar1&apos; runat=&apos;server&apos; Email=&apos;username@domain.com&apos; /&gt;
</pre>
<p>For my email address, I get the following:</p>
<p><img src="http://farm3.static.flickr.com/2181/2283724305_24797cd8d5_o.gif" width="505" height="208" alt="Output for my email address" /></p>
<p>And if we look at the generated source:</p>
<pre class="code">
&lt;a id=&quot;Gravatar1&quot; href=&quot;http://www.gravatar.com&quot; title=&quot;Get your avatar&quot;&gt;&lt;img width=&quot;80&quot; height=&quot;80&quot; src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=ccf3b8c638f15d005e5d070aeb1a3923&amp;rating=G&amp;size=80&quot; alt=&quot;Gravatar&quot; /&gt;&lt;/a&gt;
</pre>
<p>The default produces a hyperlink off to the <a href="http://www.gravatar.com">Gravatar</a> site with a title &#8220;Get your avatar&#8221;.  The image contains the MD5 email hash, a rating of &#8220;G&#8221; (suitable for all audience types), and a size of 80.</p>
<h3>Customisation</h3>
<p>The control supports a number of properties supporting the customisation of its output.</p>
<h4>Size</h4>
<p>The size property of the control can be in the range 1 to 80.  If it is outside this range, a default of 80 will be used.</dd>
<h4>MaxAllowedRating</h4>
<p>The &#8216;highest&#8217; allowed rating of image.</p>
<ul>
<li>A G rated gravatar is suitable for display on all websites with any audience type.</li>
<li>PG rated gravatars contain may contain rude gestures, provocatively dressed individuals, the lesser swear words, or mild violence.</li>
<li>R rated gravatars may contain such things as harsh profanity, intense violence, nudity, or hard drug use.</li>
<li>X rated gravatars may contain hardcore sexual imagery or extremely disturbing violence.</li>
</ul>
<h4>OutputGravatarSiteLink</h4>
<p>True by default, determines whether a hyperlink linking to the gravatar website will be output around the image.</p>
<h4>LinkTitle</h4>
<p>&#8220;Get your avatar&#8221; by default, allows the customisation of the &#8216;title&#8217; attribute of the link (obviously doesn&#8217;t apply if OutputGravatarSiteLink property is set to false.)</p>
<h4>DefaultImage</h4>
<p>URL encoded URL, protocol included, of a GIF, JPEG, or PNG image that should be returned if either the requested email address has no associated gravatar, or that gravatar has a rating higher than is allowed by the &#8220;MaxAllowedRating&#8221; property.</p>
<p>The code snippet below shows the associated properties.</p>
<pre class="code">
&lt;fcm:Gravatar ID=&quot;Gravatar1&quot; runat=&quot;server&quot;
    Email=&quot;username@domain.com&quot;
    DefaultImage=&quot;http://www.site.com/default.jpg&quot;
    OutputGravatarSiteLink=&quot;true&quot; Size=&quot;40&quot; /&gt;
</pre>
<h3>Download and Get Started</h3>
<p>You can <a href='http://www.freshclickmedia.com/wp-content/uploads/2008/02/gravatar.zip' title='gravatar.zip'>download the Gravatar Custom Control here</a>.  Once you&#8217;ve extracted the assembly from the ZIP file, add to the Visual Studio toolbox by right clicking on the toolbox and selecting &#8220;Choose Items&#8221; from the context menu.  Browse to the assembly (Freshclickmedia.Web.dll), and click &#8220;OK&#8221; to add.</p>
<p><img src="http://farm3.static.flickr.com/2064/2283724303_c96532e03b_o.gif" alt="Adding the control to the toolbox" width="505" height="361"  /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.freshclickmedia.com/blog/2008/02/gravatar-aspnet-control/feed/</wfw:commentRss>
		<slash:comments>45</slash:comments>
		</item>
		<item>
		<title>Your first ASP.NET Custom Control</title>
		<link>http://www.freshclickmedia.com/blog/2007/12/your-first-aspnet-custom-control/</link>
		<comments>http://www.freshclickmedia.com/blog/2007/12/your-first-aspnet-custom-control/#comments</comments>
		<pubDate>Sun, 02 Dec 2007 19:44:50 +0000</pubDate>
		<dc:creator>Shane</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.freshclickmedia.com/blog/2007/12/your-first-aspnet-custom-control/</guid>
		<description><![CDATA[One of the strengths of ASP.NET is the ability to write your own reusable custom controls, deploy them, and use them by simply dragging them onto a form from the toolbox. This tutorial walks through the implementation of a &#8216;TimePicker&#8217; custom control. In particular, it pays attention to: Deriving from the WebControl class, and customising [...]]]></description>
			<content:encoded><![CDATA[<p>One of the strengths of ASP.NET is the ability to write your own reusable custom controls, deploy them, and use them by simply dragging them onto a form from the toolbox.  This tutorial walks through the implementation of a &#8216;TimePicker&#8217; custom control.</p>
<p><span id="more-3"></span></p>
<p>In particular, it pays attention to:</p>
<ul>
<li>Deriving from the WebControl class, and customising the control&#8217;s output using the HtmlTextWriter class;</li>
<li>Customising the control using properties;</li>
<li>Adding the control to the Visual Studio toolbox and adding to a page;</li>
<li>Dealing with Postback data;</li>
<li>Validating the control like a typical web control</li>
</ul>
<p>The TimePicker control is a drop down list containing times separated by a user-definable time-period, such as 15 minutes. The <a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.webcontrol(VS.71).aspx" title="WebControl class documentation on MSDN" target="_blank">WebControl class</a> provides a good foundation for custom control development in that it provides a number of methods, properties and events common to web controls in ASP.NET.</p>
<p>To start, create a new class library in Visual Studio.  In this case, I&#8217;ll mimick the Microsoft naming standards and call it Freshclickmedia.Web.</p>
<p><img src="http://farm3.static.flickr.com/2198/2080836411_288894e9a6_o.gif" alt="Creating the control class library" /></p>
<p>To further mimick the Microsoft namespace hiearchy, I have created UI and WebControls folders.</p>
<p><img src="http://farm3.static.flickr.com/2163/2081638246_a94ba9d137_o.gif" alt="Initial Project Layout" /></p>
<p>One this has been done, right click on the project and select &#8216;add new item&#8217;.  Add a new item of type &#8216;Web Custom Control&#8217; called .</p>
<p><img src="http://farm3.static.flickr.com/2208/2081648644_8744737dcf_o.gif" alt="Adding a custom control to the project" /></p>
<p>Once the new control has been added, there will be a lot of default, but unwanted code.  Remove the class data so that you end up with something like this:</p>
<pre class="code">
[ToolboxData("&lt;{0}:TimePicker runat=server&gt;")]
public class TimePicker : WebControl{protected override void RenderContents(HtmlTextWriter output)
{

}</pre>
<p>The first line is an attribute that defines what text will be added to a webform when the control is dragged from the toolbox.  More on this later.</p>
<p>The class contains a single overridden WebControl method, RenderContents.   The HtmlTextWriter class parameter allows control developers to customise the HTML markup that is rendered by the control at runtime, and it is this method that we&#8217;ll look at first.</p>
<p>By default, a class inheriting from WebControl will have a default &#8216;outer&#8217; HTML element of type Span.  We&#8217;re looking to write a Select, so we&#8217;ll add a constructor to specify this outer HTML element type:</p>
<pre class="code">
///
/// Constructor defining outer HTML element type
///
public TimePicker() : base( HtmlTextWriterTag.Select)
{

}</pre>
<p>Now when the control is used, the outer tag will be of type Select, which is what we want.  However, to output our times, we&#8217;ll need to go back to the RenderContents method.  In this simple example, we&#8217;ll write out a list of times.  Before we do this, we need to specify some properties as follows:</p>
<ul>
<li>The default text, such as &#8216;Select time&#8217;;</li>
<li>The minute increment for the control</li>
<li>The selected value on a Page postback</li>
</ul>
<p>Shown below is the code for those properties.  Note that each one uses the ViewState to persist the information across postbacks, and have default values of &#8220;Select Time&#8221;, 15, and string.Empty respectively.</p>
<pre class="code">
///
/// Gets or sets the default selection text.
///
public string DefaultSelectionText
{
  get { return ViewState["DefaultSelectionText"] == null ? "Select time" : (string)ViewState["DefaultSelectionText"]; }
  set { ViewState["DefaultSelectionText"] = value; }
}

///
/// Gets or sets the minute increment.
///
public int MinuteIncrement
{
  get { return ViewState["MinuteIncrement"] == null ? 15 : (int)ViewState["MinuteIncrement"]; }
  set { ViewState["MinuteIncrement"] = value; }
}

///
/// Gets or sets the selected value.
///
public string SelectedValue
{
  get { return ViewState["SelectedValue"] == null ? string.Empty : (string)ViewState["SelectedValue"]; }
  set { ViewState["SelectedValue"] = value; }
}</pre>
<p>To keep things simple, the RenderContents method will simply loop from 00:00 to the last available time, based on the MinuteIncrement property value.   The code is shown below:</p>
<pre class="code">
protected override void RenderContents(HtmlTextWriter writer)
{
  // write out the options:
  writer.Write("&lt;option value=\"\"{0}&gt;{1}&lt;/option&gt;", string.IsNullOrEmpty(SelectedValue) ? " selected=\"selected\"" : "", DefaultSelectionText);

  int minuteIncrement = Convert.ToInt32(MinuteIncrement);

  // 24 hours in a day, 60 minutes in an hour, 24 * 60 = 1440
  for (int minuteLoop = 0; minuteLoop &lt; 1440; minuteLoop += minuteIncrement)
  {
    // convert the minuteLoop value to a meaningful time:
    int hours = minuteLoop / 60;
    int leftOverMinutes = minuteLoop % 60;

    string time = string.Format("{0:00}:{1:00}", hours, leftOverMinutes);

    writer.Write( "&lt;option{0} value=\"{1}\"&gt;{2}&lt;/option&gt;", time == SelectedValue ? " selected=\"selected\"" : "", time, time);
  }

  base.RenderContents(writer);
}</pre>
<p>The key points from the code are that a series of &lt;option&gt; tags are written to the browser.  Some logic is included to determine whether the current option is the selected value, in which case a &#8216;selected&#8217; attribute is written out for that option value.</p>
<p>Before using the control, let&#8217;s spend a moment on adding it to the toolbox, and also customising the default toolbox image for the control.  To use a custom toolbox image, add a 16&#215;16 image of type .bmp to the same directory as the control class.  After the image has been added to the project, select properties and select the &#8216;Build Action&#8217; to be &#8216;Embedded Resource&#8217;.</p>
<p><img src="http://farm3.static.flickr.com/2155/2080883539_f193403008_o.gif" alt="Customising the toolbox icon for the control" /></p>
<p>Once the control has been built, do the following to add the control to the toolbox.</p>
<ol>
<li>[Optional] Right click on the toolbox and select &#8216;Add tab&#8217;.  Enter a name for the tab and press enter.</li>
<li>Right click on a tab and select &#8216;Choose items&#8230;&#8217;</li>
<li>Browse for the control assembly</li>
<li>Click OK to add the control to the toolbox.<img src="http://www.freshclickmedia.com/blog/wp-content/uploads/2007/10/addingtotoolbox.gif" alt="Adding the custom control to the toolbox" /></li>
</ol>
<p>So, once the control has been added, using it is as simple as dragging it from the toolbox onto a web form.</p>
<pre class="code">
&lt;form id="form1" runat="server"&gt;
	&lt;cc1:timepicker id="TimePicker1" runat="server"&gt;&lt;/cc1:timepicker&gt;
	&lt;asp:button id="Button1" runat="server" text="Submit"&gt;&lt;/asp:button&gt;
&lt;/form&gt;</pre>
<p>The markup shown above shows a very simple ASPX page with a time picker control and a button that will initiate a postback.</p>
<p>When we view it in the browser, we get the following:</p>
<p><img src="http://farm3.static.flickr.com/2239/2081686310_1b33c2800e_o.gif" alt="TimePicker control rendering with property customisation" /></p>
<p>This all looks great &#8211; exactly what we wanted, but there is one huge remaining issue.  If we click the submit button, the selected time is lost, so the control may look right, but functionally it&#8217;s rather useless if we can&#8217;t access the selected time, and the selected time doesn&#8217;t persist visually on the page across page postbacks.</p>
<p>To sort out the postback issue, we must implement 3 things:</p>
<ul>
<li>Derive our control from IPostBackDataHandler, and implement the 2 interface methods, LoadPostData and RaisePostDataChangedEvent.</li>
<li>Output an HTML &#8216;name&#8217; attribute to the rendering output so that the form can pick up the control&#8217;s submitted data.</li>
<li>Call RegisterRequiresPostback to indicate that the control requires page postback data handling.</li>
</ul>
<p>Implementing the IPostBackDataHandler interface results in the following class definition change:</p>
<pre class="code">
public class TimePicker : WebControl, IPostBackDataHandler</pre>
<p>The 2 interface methods, LoadPostData and RaisePostDataChangedEvent are coded as follows:</p>
<pre class="code">
public virtual bool LoadPostData(string postDataKey, NameValueCollection values)
{
  SelectedValue = Convert.ToString(values[this.UniqueID]);
  return false;
}

public void RaisePostDataChangedEvent()
{
  // Part of the IPostBackDataHandler contract.  Invoked if we ever returned true from the
  // LoadPostData method (indicates that we want a change notification raised).  Since we
  // always return false, this method is just a no-op.
}</pre>
<p>The LoadPostData retrieves information from the posted form data and assigns it to the SelectedValue property of the control.</p>
<p>The RaisePostDataChangedEvent method is an essential method here, since we&#8217;re inheriting from IPostBackDataHandler.  However, it is only  invoked if the LoadPostData method returns true, and in our case it returns false.  Returning true can be used to raise event based on changed data, but that is beyond the scope of this tutorial.</p>
<p>We also need to output an HTML &#8216;name&#8217; attribute to the control&#8217;s output, since this is what will be used to identify the control&#8217;s data when the form is posted to the server.  To do this, override the base class&#8217; AddAttributesToRender method:</p>
<pre class="code">
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
  writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
  base.AddAttributesToRender(writer);
}</pre>
<p>The last thing is to override the base class&#8217; OnPreRender method, to allow us to notify the page on which the control is hosted that the control requires post back handling:</p>
<pre class="code">
protected override void OnPreRender(EventArgs e)
{
  base.OnPreRender(e);    

  if (Page != null)
  {
    Page.RegisterRequiresPostBack(this);
  }
}</pre>
<p>Rebuilding will now fix the posting back issue, and the control will retain it&#8217;s selected value property.</p>
<p>Another issue with the control that&#8217;s very easy to implement is validation.  Placing a RequiredFieldAttribute on the page and associating it to the TimePicker control will result in the following error:</p>
<p><img src="http://farm3.static.flickr.com/2217/2081706952_acaeb960b2_o.gif" alt="Validation error on the TimePicker Control" /></p>
<p>To resolve this issue, simply add a ValidationProperty attribute to the control class:</p>
<pre class="code">
[ValidationProperty("SelectedValue")]
public class TimePicker : WebControl, IPostBackDataHandler</pre>
<p>Adding this simple line will give us nice co-operation with the ASP.NET validator controls.</p>
<p><img src="http://farm3.static.flickr.com/2110/2080931083_0799de7bd0_o.gif" alt="Validation fixed" /></p>
<p>So, that&#8217;s it for a simple custom control.  In future, I&#8217;ll be doing something slightly more interesting, as I look at integrating JavaScript within a control.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freshclickmedia.com/blog/2007/12/your-first-aspnet-custom-control/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Deleting directory on ASP.NET 2.0 site causes Session invalidation</title>
		<link>http://www.freshclickmedia.com/blog/2007/10/deleting-directory-on-aspnet-20-site-causes-session-invalidation/</link>
		<comments>http://www.freshclickmedia.com/blog/2007/10/deleting-directory-on-aspnet-20-site-causes-session-invalidation/#comments</comments>
		<pubDate>Mon, 22 Oct 2007 23:59:47 +0000</pubDate>
		<dc:creator>Shane</dc:creator>
				<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://www.freshclickmedia.com/blog/2007/10/deleting-directory-on-aspnet-20-site-causes-session-invalidation/</guid>
		<description><![CDATA[The other day, I had a niggling issue with session data. Initially, I could see no reason for my in-proc session data being lost between postbacks.After commenting out some code, I realised that deleting a sub-directory was causing the issue. In my case, I was creating sub-directories and saving files into them, to be downloaded [...]]]></description>
			<content:encoded><![CDATA[<p>The other day, I had a niggling issue with session data.  Initially, I could see no reason for my in-proc session data being lost between postbacks.<span id="more-5"></span>After commenting out some code, I realised that deleting a sub-directory was causing the issue.  In my case, I was creating sub-directories and saving files into them, to be downloaded by a user.  For housekeeping, I was deleting directories that were older than an hour, and this is where the problem arose.</p>
<p>It seems that the default session state method, in-proc, does not play well with directories being deleted.  The session is invalidated as the app domain is recycled.  This is new behaviour with version 2.0.</p>
<p>Of course, I&#8217;m not the only one who&#8217;s experienced such problems, and a suggestion to delete all the files in a directory <a href="http://http://www.vikramlakhotia.com/Deleting_Directory_in_ASPnet_20.aspx" title="Deleting all files" target="_blank">can be found here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freshclickmedia.com/blog/2007/10/deleting-directory-on-aspnet-20-site-causes-session-invalidation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
