<?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>Coded - Web Development and Programming Blog &#187; Web Programming</title>
	<atom:link href="http://www.codedblog.com/category/web-programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.codedblog.com</link>
	<description>C#, ASP.NET, Google, Remoting, AJAX, Silverlight, Web Development</description>
	<lastBuildDate>Wed, 16 Jul 2008 13:15:28 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Automatically adding ValidatorCalloutExtenders to your validators</title>
		<link>http://www.codedblog.com/2008/07/16/automatically-adding-validatorcalloutextenders-to-your-validators/</link>
		<comments>http://www.codedblog.com/2008/07/16/automatically-adding-validatorcalloutextenders-to-your-validators/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 13:05:01 +0000</pubDate>
		<dc:creator>Andrei Alecu</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Web Programming]]></category>

		<guid isPermaLink="false">http://www.codedblog.com/2008/07/16/automatically-adding-validatorcalloutextenders-to-your-validators/</guid>
		<description><![CDATA[	I recently had to work on a pretty big ASP.NET page with lots of fields that needed to be validated.
	 We thought it would be cool if we used the AJAX Toolkit ValidatorCalloutExtender control on the validators to keep the validation inline and concise.
	To quote from the AJAX Toolkit page: 
ValidatorCallout is an ASP.NET AJAX [...]]]></description>
			<content:encoded><![CDATA[	<p>I recently had to work on a pretty big ASP.NET page with lots of fields that needed to be validated.</p>
	<p><img src='http://www.codedblog.com/wp-content/uploads/2008/07/requiredfieldvalidator.png' style="padding: 3px" align="right" alt='requiredfieldvalidator.png' /> We thought it would be cool if we used the <a href="http://www.asp.net/ajax/ajaxcontroltoolkit/">AJAX Toolkit</a> <a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/ValidatorCallout/ValidatorCallout.aspx">ValidatorCalloutExtender</a> control on the validators to keep the validation inline and concise.</p>
	<p>To quote from the AJAX Toolkit page: </p>
<blockquote>ValidatorCallout is an ASP.NET AJAX extender that enhances the functionality of existing ASP.NET validators. To use this control, add an input field and a validator control as you normally would. Then add the ValidatorCallout and set its TargetControlID property to reference the validator control. </blockquote>
	<p>Because we had over 30 text fields, it would have been really tiresome to add extenders manually to each of the validators. So a way to attach them dynamically was needed.</p>
	<p>Fortunately, this is pretty easy to do by iterating through the Page.Validators collection, dynamically creating ValidatorCalloutExtender controls and adding them to the Page.</p>
	<h2>Challenges</h2>
	<ul>
		<li>The first problem I had was an error that occured when trying to dynamically add controls to the Page.Controls collection:</li>
	</ul>
	<p><span id="more-23"></span></p>
	<p><code>The Controls collection cannot be modified because the control contains code blocks (i.e. &lt;% ... %&gt;).</code></p>
	<p>
The error probably occurred because of the way I had the MasterPage set up. The solution, although more of a hack, was to add a PlaceHolder to the page and add my controls to it instead of the Page.Controls collection. I named it <strong>ValidatorsPlaceHolder</strong> (see below)</p>
	<ul>
		<li>Another problem was that the extender was being dynamically added to a different naming container than the target control, so it wouldn&#8217;t find it. </li>
	</ul>
	<p>This lead to the following error:</p>
	<p><code>Target control with ID &#039;XYZ&#039; could not be found for extender...</code></p>
	<p>The error is described in the <a href="http://forums.asp.net/t/992919.aspx">AJAX Control Toolkit FAQ</a> and the solution is to handle the <strong>ResolveControlID</strong> event and help it find the control it needs.</p>
	<p>For this to work I needed to create an <strong>Extension method</strong> for the <strong>Page</strong> class that would find a control by ID by looking recursively through all of its children.</p>
	<h3>Here it is below:</h3>
	<p><textarea name="code" class="csharp">namespace ExtensionMethods 
 {
    public static class ExtensionMethods
    {
        public static Control FindControlRecursive(this Control root, string id)
        {
            if (root.ID == id)
            {
                return root;
            }
            foreach (Control c in root.Controls)
            {
                Control t = FindControlRecursive(c, id);
                if (t != null)
                {
                    return t;
                }
            }
            return null;
        }
    }
 } </textarea></p>
	<p>Usage: <code>var myControl = Page.FindControlRecursive(&quot;MyControlsName1&quot;);</code></p>
	<p>Now that this we got this out of the way, here&#8217;s the full code listing for the method that adds ValidatorCalloutExtenders to all of the validators.</p>
	<h2>Code Listing</h2>
	<p><textarea name="code" class="csharp">    protected void ExtendValidators()
    {
        ValidatorsPlaceHolder.Controls.Clear();
        foreach (Control ctl in Page.Validators)
        {
            if (ctl is RequiredFieldValidator)
            {
                var validatorCtl = (RequiredFieldValidator)ctl;
                validatorCtl.Display = ValidatorDisplay.None;
                validatorCtl.SetFocusOnError = true;
            }
            else if (ctl is CompareValidator)
            {
                var validatorCtl = (CompareValidator)ctl;
                validatorCtl.Display = ValidatorDisplay.None;
                validatorCtl.SetFocusOnError = true;
            }
            else if (ctl is RegularExpressionValidator)
            {
                var validatorCtl = (RegularExpressionValidator)ctl;
                validatorCtl.Display = ValidatorDisplay.None;
                validatorCtl.SetFocusOnError = true;
            }
            if (!String.IsNullOrEmpty(ctl.ID))
            {
                var valExtender = new ValidatorCalloutExtender();
                valExtender.TargetControlID = ctl.ID;
                valExtender.ID = ctl.ID + &#8221;_ValExtender&#8221;;
                valExtender.ResolveControlID +=
                    ((sender, e) => e.Control = Page.FindControlRecursive(e.ControlID));
                ValidatorsPlaceHolder.Controls.Add(valExtender);
            }
        }
    }</textarea></p>
	<p>Notice the .ResolveControlID event handler written as a lambda. It uses the FindControlRecursive extension method shown above to help the Extender find the target control, because it will not be able to do it by itself.</p>


 ]]></content:encoded>
			<wfw:commentRss>http://www.codedblog.com/2008/07/16/automatically-adding-validatorcalloutextenders-to-your-validators/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to auto zoom and auto center Google Maps</title>
		<link>http://www.codedblog.com/2007/09/28/how-to-auto-zoom-and-auto-center-google-maps/</link>
		<comments>http://www.codedblog.com/2007/09/28/how-to-auto-zoom-and-auto-center-google-maps/#comments</comments>
		<pubDate>Fri, 28 Sep 2007 16:03:45 +0000</pubDate>
		<dc:creator>Andrei Alecu</dc:creator>
				<category><![CDATA[User Interface]]></category>
		<category><![CDATA[Web Programming]]></category>

		<guid isPermaLink="false">http://www.codedblog.com/2007/09/28/how-to-auto-zoom-and-auto-center-google-maps/</guid>
		<description><![CDATA[	This post discusses how to auto center and auto zoom a Google Map to display all of the markers optimally.
	In order to get accomplish this, you have to calculate the center point and zoom level manually via code. Fortunately this is pretty easy to do, you just need to calculate the minimum and maximum latitude/longitude [...]]]></description>
			<content:encoded><![CDATA[	<p>This post discusses how to auto center and auto zoom a <a href="http://www.google.com/apis/maps/">Google Map</a> to display all of the markers optimally.</p>
	<p>In order to get accomplish this, you have to calculate the center point and zoom level manually via code. Fortunately this is pretty easy to do, you just need to calculate the minimum and maximum latitude/longitude of all of your markers and then get the center point of the resulting area (which will be a rectangle).<span id="more-22"></span></p>
	<p>I&#8217;m using the <a href="http://en.googlemaps.subgurim.net/">Google Maps for ASP.NET control by Subgurim</a>, but this method should apply to any other control, and should even work with plain JavaScript.</p>
	<h3>Auto center</h3>
	<p>First, you will need to find out the min/max latitude and longitude for your markers, this can usually be done in one pass at the same time as you add them. Here&#8217;s some Visual Basic.NET code to help you out (I&#8217;m using VB.NET for this project at the request of my collaborator, but it should be easy to convert to C# &#8211; think of it as pseudo code):</p>
	<p><textarea name="code" class="vb">
        Dim minLongitude As Single = Nothing
        Dim maxLongitude As Single = Nothing
        Dim minLatitude As Single = Nothing
        Dim maxLatitude As Single = Nothing
        &#8217;
        &#8217; add markers 
        For i As Integer = 0 To dataSet.Tables(0).Rows.Count &#8211; 1
            Dim glatlng As New GLatLng
            glatlng.lat = dataSet.Tables(0).Rows(i).Item(&#8220;latitude&#8221;)
            glatlng.lng = dataSet.Tables(0).Rows(i).Item(&#8220;longitude&#8221;)
            &#8217;
            &#8217; First time initialization of the variables
            If minLongitude = Nothing Then minLongitude = glatlng.lng
            If maxLongitude = Nothing Then maxLongitude = glatlng.lng
            If minLatitude = Nothing Then minLatitude = glatlng.lat
            If maxLatitude = Nothing Then maxLatitude = glatlng.lat
            &#8217;
            minLongitude = Math.Min(minLongitude, glatlng.lng)
            maxLongitude = Math.Max(maxLongitude, glatlng.lng)
            minLatitude = Math.Min(minLatitude, glatlng.lat)
            maxLatitude = Math.Max(maxLatitude, glatlng.lat)
            &#8217;
            &#8217; Other code here&#8230;
        Next</textarea></p>
	<p>You then just need to calculate the center point of the resulting area. This is as easy as:</p>
	<p><textarea name="code" class="vb">
        centerLatitude = minLatitude + (maxLatitude &#8211; minLatitude) / 2
        centerLongitude = minLongitude + (maxLongitude &#8211; minLongitude) / 2</textarea></p>
	<p>You can now center your map widget to these coordinates.</p>
	<h3>Auto zoom</h3>
	<p>The auto zoom part is where it gets a little tricky. In my application I&#8217;m calculating the distance in miles from the minLatitude, minLongitude coordinate to the maxLatitude, maxLongitude coordinate.</p>
	<p>The formula for calculating the distance in miles between two coordinates is:</p>
	<p><pre><code>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;miles = (3958.75 * Math.Acos(Math.Sin(latitude1 / 57.2958) * Math.Sin(latitude2 / 57.2958) + Math.Cos(latitude1 / 57.2958) * Math.Cos(latitude2 / 57.2958) * Math.Cos(longitude2 / 57.2958 - longitude1 / 57.2958)))
</code></pre></p>
	<p>By calculating how many miles your markers span, you can make an informed guess on which zoom level to use. For instance, if the distance between the furthest two markers is less than 0.2 miles, then you could use the maximum zoom level available&#8212;which is <strong>16</strong> by the way&#8212;; if the distance is more than 0.2 miles and less than 0.5 miles&#8212;use zoom level 15, and so on.</p>
	<p>Here&#8217;s a list of zoom levels for distances up to 15 miles:</p>
	<p><textarea name="code" class="vb">
        Select Case miles
            Case Is < 0.2
                GMap1.GZoom = 16
            Case Is < 0.5
                GMap1.GZoom = 15
            Case Is < 1
                GMap1.GZoom = 14
            Case Is < 2
                GMap1.GZoom = 13
            Case Is < 3
                GMap1.GZoom = 12
            Case Is < 7
                GMap1.GZoom = 11
            Case Is < 15
                GMap1.GZoom = 10
            Case Else
                GMap1.GZoom = 9
        End Select</textarea></p>
	<p>That&#8217;s it, your map should now be able to auto zoom and auto center itself on your markers!</p>
	<p>[tags]Google Maps API, Visual Basic.NET[/tags]</p>

 ]]></content:encoded>
			<wfw:commentRss>http://www.codedblog.com/2007/09/28/how-to-auto-zoom-and-auto-center-google-maps/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Generating a transparent GIF image using C#</title>
		<link>http://www.codedblog.com/2007/08/28/generating-a-transparent-gif-image-using-c/</link>
		<comments>http://www.codedblog.com/2007/08/28/generating-a-transparent-gif-image-using-c/#comments</comments>
		<pubDate>Tue, 28 Aug 2007 13:31:06 +0000</pubDate>
		<dc:creator>Andrei Alecu</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Web Programming]]></category>

		<guid isPermaLink="false">http://www.codedblog.com/?p=5</guid>
		<description><![CDATA[	Problem:
	There is apparently no easy way to generate a transparent GIF image using the .NET framework. Microsoft provided a method in the Bitmap class called MakeTransparent() but it doesn&#8217;t work for GIFs, it only seems to work for PNGs.
	To create a transparent GIF you need to recreate the color table of the image using Imaging [...]]]></description>
			<content:encoded><![CDATA[	<h3>Problem:</h3>
	<p>There is apparently no easy way to generate a transparent GIF image using the .NET framework. Microsoft provided a method in the Bitmap class called <a href="http://msdn2.microsoft.com/en-us/library/system.drawing.bitmap.maketransparent.aspx">MakeTransparent()</a> but it doesn&#8217;t work for GIFs, it only seems to work for PNGs.</p>
	<p>To create a transparent GIF you need to recreate the color table of the image using Imaging APIs, as detailed in <a href="http://support.microsoft.com/default.aspx?scid=kb%3bEN-US%3bQ319061">this KB article</a> . Unfortunately, this can be pretty slow for an ASP.NET Web application, and it has a lot of overhead, so I needed an alternative.<span id="more-5"></span></p>
	<h3>Solution:</h3>
	<p>The alternative is to alter the color table directly using the GIF specification. To implement this, I needed to save the non-transparent GIF to a MemoryStream, and then go through the binary data, updating the color table with the new transparency bits.</p>
	<p><em>The original code for this function is not my own, I have found it somewhere on the Internet and modified it. Unfortunately I can&#8217;t remember where I found it, so I can&#8217;t give credit, but if you know the original author please add a comment.</em></p>
	<h3>Source:</h3>
	<p><textarea name="code" class="csharp">
    /// <summary>
    /// Returns a transparent background GIF image from the specified Bitmap.
    /// </summary>
    /// <param name="bitmap">The Bitmap to make transparent.</param>
    /// <param name="color">The Color to make transparent.</param>
    /// <returns>New Bitmap containing a transparent background gif.</returns>
    public Bitmap MakeTransparentGif(Bitmap bitmap, Color color)
    {
        byte R = color.R;
        byte G = color.G;
        byte B = color.B;</p>
        MemoryStream fin = new MemoryStream();
        bitmap.Save(fin, System.Drawing.Imaging.ImageFormat.Gif);
        MemoryStream fout = new MemoryStream((int)fin.Length);
        int count = 0;
        byte[] buf = new byte[256];
        byte transparentIdx = 0;
        fin.Seek(0, SeekOrigin.Begin);
        //header
        count = fin.Read(buf, 0, 13);
        if ((buf[0] != 71) || (buf[1] != 73) || (buf[2] != 70)) return null; //GIF
        fout.Write(buf, 0, 13);
        int i = 0;
        if ((buf[10] &#38; 0&#215;80) > 0)
        {
            i = 1 << ((buf[10] &#38; 7) + 1) == 256 ? 256 : 0;
        }
        for (; i != 0; i&#8212;)
        {
            fin.Read(buf, 0, 3);
            if ((buf[0] == R) &#38;&#38; (buf[1] == G) &#38;&#38; (buf[2] == B))
            {
                transparentIdx = (byte)(256 &#8211; i);
            }
            fout.Write(buf, 0, 3);
        }
        bool gcePresent = false;
        while (true)
        {
            fin.Read(buf, 0, 1);
            fout.Write(buf, 0, 1);
            if (buf[0] != 0&#215;21) break;
            fin.Read(buf, 0, 1);
            fout.Write(buf, 0, 1);
            gcePresent = (buf[0] == 0xf9);
            while (true)
            {
                fin.Read(buf, 0, 1);
                fout.Write(buf, 0, 1);
                if (buf[0] == 0) break;
                count = buf[0];
                if (fin.Read(buf, 0, count) != count) return null;
                if (gcePresent)
                {
                    if (count == 4)
                    {
                        buf[0] |= 0&#215;01;
                        buf[3] = transparentIdx;
                    }
                }
                fout.Write(buf, 0, count);
            }
        }
        while (count > 0)
        {
            count = fin.Read(buf, 0, 1);
            fout.Write(buf, 0, 1);
        }
        fin.Close();
        fout.Flush();
        return new Bitmap(fout);
    }</textarea>
	<p><a href="http://www.codedblog.com/wp-content/uploads/2007/08/giftransparencydemo.zip">Download ASP.NET GIF Transparency Demo WebForm</a><br />
[tags]C#, GIF, Transparent GIF, ASP.NET, Bitmap, System.Graphics[/tags]</p>

 ]]></content:encoded>
			<wfw:commentRss>http://www.codedblog.com/2007/08/28/generating-a-transparent-gif-image-using-c/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
