<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>ASP.NET AJAX</title>
        <link>http://blogs.interakting.co.uk/brad/category/93.aspx</link>
        <description>ASP.NET AJAX ,formerly code-named Atlas, is a set of extensions to ASP.NET developed by Microsoft for implementing Ajax functionality.

Including both client-side and server-side components, ASP.NET AJAX allows the developer to create web applications in ASP.NET 2.0 (and to a limited extent in other environments) which can update data on the web page without a complete reload of the page. The key technology which enables this functionality is the XMLHttpRequest object, along with Javascript and DHTML.

ASP.NET AJAX was released as a standalone extension to ASP.NET in January 2007 after a lengthy period of beta-testing. It was subsequently included with version 3.5 of the .NET Framework, which was released alongside Visual Studio 2008 in November 2007.

The core technology builds upon the same concept as Anthem.NET, which is one of the earliest serious implementations of WYSIWYG ASP.NET Ajax Technology. After an Ajax request, the HTML within some portions o</description>
        <language>en-GB</language>
        <copyright>Brad</copyright>
        <managingEditor>pbradley@businessdecision.co.uk</managingEditor>
        <generator>Subtext Version 1.9.5.177</generator>
        <item>
            <title>C#: Google Map Server Control - Part 2 - Custom EPiServer Property</title>
            <link>http://blogs.interakting.co.uk/brad/archive/2008/06/09/C-Google-Map-Server-Control---Part-2---Custom.aspx</link>
            <description>&lt;p&gt;This post tells you how to take what I discussed in &lt;a title="Click here to read part one" href="http://blogs.interakting.co.uk/brad/archive/2008/06/06/C-Google-Map-Server-Control---Part-1.aspx" target="_blank"&gt;Part 1&lt;/a&gt; and turn it into a custom EPiServer property, so CMS user's can simply enter a postcode and it will call of to Google's Local Search API, return the Coordinates for the postcode and plot a marker on the map. The user can then drag the marker for a more exact location, set the zoom level and finally the type of map (Normal, Satellite or Hybrid). The data is then rendered on the public site using the code from &lt;a title="Click here to read part one" href="http://blogs.interakting.co.uk/brad/archive/2008/06/06/C-Google-Map-Server-Control---Part-1.aspx" target="_blank"&gt;Part 1&lt;/a&gt;. The screenshot below show's how it will look in EPiServer (click the thumbnail for the full size version):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.interakting.co.uk/images/blogs_interakting_co_uk/brad/WindowsLiveWriter/CGoogleMapServerControlPart2CustomEPiSer_ED99/GoogleMapEPiServer_2.jpg"&gt;&lt;img style="border-right: 0px; border-top: 0px; margin: 0px 10px 0px 0px; border-left: 0px; border-bottom: 0px" height="243" alt="GoogleMapEPiServer" src="http://blogs.interakting.co.uk/images/blogs_interakting_co_uk/brad/WindowsLiveWriter/CGoogleMapServerControlPart2CustomEPiSer_ED99/GoogleMapEPiServer_thumb.jpg" width="222" align="left" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Creating a custom EPiServer property is relatively easy - although I think I've not quite got the hang of how to store the actual data. It must be converted to a string for storage in the database. I started to use an &lt;em&gt;XmlSerializer&lt;/em&gt; but got confused (mainly as the JavaScript was doing my head in) as to where i should be doing the serialisation. Sadly the only example i could find on the net was how to create a custom property that was a string - about as much use as a chocolate fire guard! So here's my way of doing it - using a comma separated string (dirty I know!) - please feel free to show me the correct way.&lt;/p&gt;  &lt;p&gt;EPiServer properties are split into two parts, the data and UI aspects. The first is how the data is persisted into the database, the second controls how the data is rendered to the page for both the public and on the edit page in the CMS.   &lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1) &lt;em&gt;CoordinateProperty.cs&lt;/em&gt;&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;Firstly mark your class with the following attribute: &lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;   &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;[Serializable]
[PageDefinitionTypePlugIn(
    DisplayName = &lt;span style="color: #006080"&gt;"Coordinate"&lt;/span&gt;, 
    Description = &lt;span style="color: #006080"&gt;"Coordinate for use with (Google) Map Control"&lt;/span&gt;)]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; CoordinateProperty : PropertyData&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next some properties to help control the map:&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _string;

&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;? Latitude
{
    get
    {
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(String) &amp;amp;&amp;amp; String.Contains(&lt;span style="color: #006080"&gt;','&lt;/span&gt;))
        {
            &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; temp = 0;
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;.TryParse(String.Split(&lt;span style="color: #006080"&gt;','&lt;/span&gt;)[0].Trim(), &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; temp))
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; temp;
            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
        }
        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
     }
 }
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt;? Longitude
{
    get
    {
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(String) &amp;amp;&amp;amp; String.Contains(&lt;span style="color: #006080"&gt;','&lt;/span&gt;))
        {
            &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; temp = 0;
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;.TryParse(String.Split(&lt;span style="color: #006080"&gt;','&lt;/span&gt;)[1].Trim(), &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; temp))
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; temp;
            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
        }
        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
    }
}
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Zoom
{
    get
        {
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(String) &amp;amp;&amp;amp; String.Contains(&lt;span style="color: #006080"&gt;','&lt;/span&gt;))
        {
            &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; temp = 0;
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;.TryParse(String.Split(&lt;span style="color: #006080"&gt;','&lt;/span&gt;)[2].Trim(), &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; temp))
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; temp;
            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; 5;
         }
         &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; 5;
    }
}
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; MapType
{
    get
    {
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(String) &amp;amp;&amp;amp; String.Contains(&lt;span style="color: #006080"&gt;','&lt;/span&gt;))
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; String.Split(&lt;span style="color: #006080"&gt;','&lt;/span&gt;)[3].Trim();
        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #006080"&gt;"Map"&lt;/span&gt;;
    }
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next the implementation for the abstract members of &lt;em&gt;PropertyData&lt;/em&gt;.&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; PropertyDataType Type
{
    get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; PropertyDataType.LongString; }
}
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; Type PropertyValueType
{
    get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetType(); }
}
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Value
{
    get
    {
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.IsNull)
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.String;
    }
    set
    {
        &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.ThrowIfReadOnly();
        &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.SetPropertyValue(&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt;
        {
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.String = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;.ToString();
        });
    }
}
[XmlIgnore]
&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; String
{
    get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._string; }
    set
    {
        &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.ThrowIfReadOnly();
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (PropertyData.QualifyAsNullString(&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;))
            &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.Clear();
        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._string != &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;) || (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.IsNull))
        {
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._string = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.Modified();
        }
    }
}
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; PropertyData ParseToObject(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; str)
{
    XmlSerializer SerializerObj = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; XmlSerializer(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetType());
    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (TextReader stream = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StringReader(str))
    {
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (CoordinateProperty)SerializerObj.Deserialize(stream);
    }
}
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ParseToSelf(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; str)
{
    String = str;
}
&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SetDefaultValue()
{
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.String = &lt;span style="color: #006080"&gt;",,5,Map"&lt;/span&gt;;
}
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; IPropertyControl CreatePropertyControl()
{
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CoordinatePropertyControl();
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;2) &lt;u&gt;&lt;em&gt;CoordinatePropertyControl.cs&lt;/em&gt;&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With that done we now need to control how the above class is rendered. First we need to add the four Textboxes:&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;TextBox latitiude;
TextBox longitude;
TextBox zoom;
TextBox mapType;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next some basic methods, the first just makes it easier further down the line, the second is required:&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// Gets the CoordinateProperty instance for this IPropertyControl.&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// &amp;lt;value&amp;gt;The property that is to be displayed or edited.&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; CoordinateProperty CoordinateProperty
{
    get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; PropertyData &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; CoordinateProperty; }
}
&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// Does the property support in page edit&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; SupportsOnPageEdit
{
    get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;; }
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next we need to provide code to display the Google Map in VIEW (public) mode, here we'll simply use the class we created in &lt;a title="Click here to read part one" href="http://blogs.interakting.co.uk/brad/archive/2008/06/06/C-Google-Map-Server-Control---Part-1.aspx" target="_blank"&gt;Part 1&lt;/a&gt; of this post:&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// Inherited. Create a controls for rendering the property in view mode.&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CreateDefaultControls()
{
    &lt;span style="color: #008000"&gt;//Check if the Latitude and Longitude have values&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CoordinateProperty.Latitude.HasValue &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CoordinateProperty.Longitude.HasValue)
    {
        GoogleMap map = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; GoogleMap();
        map.ID = &lt;span style="color: #006080"&gt;"map"&lt;/span&gt;;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Width.IsEmpty)
            map.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(100, UnitType.Percentage);
        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
            map.Width = Width;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Height.IsEmpty)
            map.Height = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(400, UnitType.Pixel);
        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
            map.Height = Height;

        map.Latitude = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CoordinateProperty.Latitude.Value;
        map.Longitude = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CoordinateProperty.Longitude.Value;
        map.Zoom = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CoordinateProperty.Zoom;
        map.MapType = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.CoordinateProperty.MapType;
        Controls.Add(map);
    }
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Right that's the basics out of the way, now its time to control how the property is rendered in EDIT mode in the CMS, but first we need to add the JavaScript:&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; JAVASCRIPT = &lt;span style="color: #006080"&gt;@"
&amp;lt;script src="&lt;/span&gt;&lt;span style="color: #006080"&gt;"http://maps.google.com/maps?file=api&amp;amp;amp;v=2&amp;amp;amp;key={0}"&lt;/span&gt;&lt;span style="color: #006080"&gt;" type="&lt;/span&gt;&lt;span style="color: #006080"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color: #006080"&gt;"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src="&lt;/span&gt;&lt;span style="color: #006080"&gt;"http://www.google.com/uds/api?file=uds.js&amp;amp;amp;v=1.0&amp;amp;amp;key={1}"&lt;/span&gt;&lt;span style="color: #006080"&gt;" type="&lt;/span&gt;&lt;span style="color: #006080"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color: #006080"&gt;"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="&lt;/span&gt;&lt;span style="color: #006080"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color: #006080"&gt;"&amp;gt;
var map;
var localSearch = new GlocalSearch();

function usePointFromPostcode(postcode, callbackFunction) {{
    localSearch.setSearchCompleteCallback(null, 
        function() {{
            if (localSearch.results[0])
            {{        
                var resultLat = localSearch.results[0].lat;
                var resultLng = localSearch.results[0].lng;
                var point = new GLatLng(resultLat,resultLng);
                callbackFunction(point, 17);
            }}else{{
                alert("&lt;/span&gt;&lt;span style="color: #006080"&gt;"Postcode not found!"&lt;/span&gt;&lt;span style="color: #006080"&gt;");
            }}
        }});    
    localSearch.execute(postcode + "&lt;/span&gt;&lt;span style="color: #006080"&gt;", UK"&lt;/span&gt;&lt;span style="color: #006080"&gt;");
}}

function mapLoad() {{
    if (GBrowserIsCompatible()) {{
    //check map not already created!
        if(!map)
        {{
        map = new GMap2(document.getElementById("&lt;/span&gt;&lt;span style="color: #006080"&gt;"{5}"&lt;/span&gt;&lt;span style="color: #006080"&gt;"));
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());

        var mType = document.getElementById("&lt;/span&gt;&lt;span style="color: #006080"&gt;"{7}"&lt;/span&gt;&lt;span style="color: #006080"&gt;").value;
        if(mType == "&lt;/span&gt;&lt;span style="color: #006080"&gt;"Hybrid"&lt;/span&gt;&lt;span style="color: #006080"&gt;")
            map.setCenter(new GLatLng(54.622978,-2.592773), 5, G_HYBRID_MAP);
        else if(mType == "&lt;/span&gt;&lt;span style="color: #006080"&gt;"Satellite"&lt;/span&gt;&lt;span style="color: #006080"&gt;")
            map.setCenter(new GLatLng(54.622978,-2.592773), 5, G_SATELLITE_MAP);
        else
            map.setCenter(new GLatLng(54.622978,-2.592773), 5, G_NORMAL_MAP);

        GEvent.addListener(map, "&lt;/span&gt;&lt;span style="color: #006080"&gt;"zoomend"&lt;/span&gt;&lt;span style="color: #006080"&gt;", function(oldLevel, newLevel) {{
            //alert("&lt;/span&gt;&lt;span style="color: #006080"&gt;"Old Zoom: "&lt;/span&gt;&lt;span style="color: #006080"&gt;" + oldLevel + "&lt;/span&gt;&lt;span style="color: #006080"&gt;" New Level: "&lt;/span&gt;&lt;span style="color: #006080"&gt;" + newLevel);
            document.getElementById("&lt;/span&gt;&lt;span style="color: #006080"&gt;"{6}"&lt;/span&gt;&lt;span style="color: #006080"&gt;").value = newLevel;
        }});

        GEvent.addListener(map, "&lt;/span&gt;&lt;span style="color: #006080"&gt;"maptypechanged"&lt;/span&gt;&lt;span style="color: #006080"&gt;", function() {{
            document.getElementById("&lt;/span&gt;&lt;span style="color: #006080"&gt;"{7}"&lt;/span&gt;&lt;span style="color: #006080"&gt;").value = map.getCurrentMapType().getName();
            document.getElementById("&lt;/span&gt;&lt;span style="color: #006080"&gt;"{6}"&lt;/span&gt;&lt;span style="color: #006080"&gt;").value = map.getZoom();
        }});
        
        }}
    }}
}}

function addLoadEvent(func) {{
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {{
    window.onload = func;
  }} else {{
    window.onload = function() {{
      oldonload();
      func();
    }}
  }}
}}

function addUnLoadEvent(func) {{
    var oldonunload = window.onunload;
    if (typeof window.onunload != 'function') {{
      window.onunload = func;
    }} else {{
      window.onunload = function() {{
        oldonunload();
        func();
      }}
    }}
}}

function placeMarkerAtPoint(point, zoom)
{{
    if(!map)
    {{
        mapLoad();
    }}
    var marker = new GMarker(point, {{draggable: true}});
    GEvent.addListener(marker, "&lt;/span&gt;&lt;span style="color: #006080"&gt;"dragstart"&lt;/span&gt;&lt;span style="color: #006080"&gt;", function() {{
        map.closeInfoWindow();
    }});
    GEvent.addListener(marker, "&lt;/span&gt;&lt;span style="color: #006080"&gt;"dragend"&lt;/span&gt;&lt;span style="color: #006080"&gt;", function() {{
        LoadCoordinates(marker.getPoint(), document.getElementById('{2}'), document.getElementById('{3}'));
        marker.openInfoWindowHtml("&lt;/span&gt;&lt;span style="color: #006080"&gt;"Lat: "&lt;/span&gt;&lt;span style="color: #006080"&gt;" + marker.getPoint().lat() + "&lt;/span&gt;&lt;span style="color: #006080"&gt;"&amp;lt;br /&amp;gt;Lng: "&lt;/span&gt;&lt;span style="color: #006080"&gt;" + marker.getPoint().lng());
    }});
    map.clearOverlays();
    map.addOverlay(marker);
    setCenterToPoint(point, zoom);
    LoadCoordinates(point, document.getElementById('{2}'), document.getElementById('{3}'));
}}

function setCenterToPoint(point, zoom)
{{
    map.setCenter(point, parseInt(zoom));
}}

function showPointLatLng(point)
{{
    alert("&lt;/span&gt;&lt;span style="color: #006080"&gt;"Latitude: "&lt;/span&gt;&lt;span style="color: #006080"&gt;" + point.lat() + "&lt;/span&gt;&lt;span style="color: #006080"&gt;"\nLongitude: "&lt;/span&gt;&lt;span style="color: #006080"&gt;" + point.lng());
}}
function LoadCoordinates(point, txtLat, txtLng)
{{
    txtLat.value = point.lat();
    txtLng.value = point.lng();
}}

addLoadEvent(mapLoad);
addUnLoadEvent(GUnload);
&amp;lt;/script&amp;gt;"&lt;/span&gt;;

&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; EXISTING = &lt;span style="color: #006080"&gt;@"
&amp;lt;script type="&lt;/span&gt;&lt;span style="color: #006080"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color: #006080"&gt;"&amp;gt;
    placeMarkerAtPoint(new GLatLng({0},{1}),{2});
&amp;lt;/script&amp;gt;"&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// Create the controls needed to edit the property&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CreateEditControls()
{
    &lt;span style="color: #008000"&gt;//Create controls required to edit the property&lt;/span&gt;
    latitiude = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TextBox();
    longitude = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TextBox();
    zoom = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TextBox();
    mapType = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TextBox();
    Label lLat = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Label();
    Label lLong = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Label();
    Label lZoom = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Label();
    Label lMapType = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Label();
    Literal brk1 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Literal();
    Literal brk2 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Literal();
    Literal brk3 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Literal();
    Literal brk4 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Literal();
    Label lPost = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Label();
    TextBox txtPostCode = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TextBox();
    Button btn = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Button();
    Panel Div = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Panel();

    &lt;span style="color: #008000"&gt;//Set the line break text.&lt;/span&gt;
    brk1.Text = &lt;span style="color: #006080"&gt;"&amp;lt;br /&amp;gt;"&lt;/span&gt;;
    brk2.Text = &lt;span style="color: #006080"&gt;"&amp;lt;br /&amp;gt;"&lt;/span&gt;;
    brk3.Text = &lt;span style="color: #006080"&gt;"&amp;lt;br /&amp;gt;"&lt;/span&gt;;
    brk4.Text = &lt;span style="color: #006080"&gt;"&amp;lt;br /&amp;gt;"&lt;/span&gt;;

    &lt;span style="color: #008000"&gt;//Set the Latitude TextBox properties&lt;/span&gt;
    latitiude.ID = &lt;span style="color: #006080"&gt;"latitiude"&lt;/span&gt;;
    latitiude.Style.Add(System.Web.UI.HtmlTextWriterStyle.MarginLeft, &lt;span style="color: #006080"&gt;"20px"&lt;/span&gt;);
    latitiude.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(140, UnitType.Pixel);

    &lt;span style="color: #008000"&gt;//Set the Longitude TextBox properties&lt;/span&gt;
    longitude.ID = &lt;span style="color: #006080"&gt;"longitude"&lt;/span&gt;;
    longitude.Style.Add(System.Web.UI.HtmlTextWriterStyle.MarginLeft, &lt;span style="color: #006080"&gt;"20px"&lt;/span&gt;);
    longitude.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(140, UnitType.Pixel);

    &lt;span style="color: #008000"&gt;//Set the Postcode TextBox properties&lt;/span&gt;
    txtPostCode.ID = &lt;span style="color: #006080"&gt;"postcode"&lt;/span&gt;;
    txtPostCode.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(140, UnitType.Pixel);
    txtPostCode.Style.Add(System.Web.UI.HtmlTextWriterStyle.MarginLeft, &lt;span style="color: #006080"&gt;"20px"&lt;/span&gt;);
    txtPostCode.Style.Add(&lt;span style="color: #006080"&gt;"text-transform"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"uppercase"&lt;/span&gt;);

    &lt;span style="color: #008000"&gt;//Set the MapType TextBox properties&lt;/span&gt;
    mapType.ID = &lt;span style="color: #006080"&gt;"maptype"&lt;/span&gt;;
    mapType.Style.Add(System.Web.UI.HtmlTextWriterStyle.MarginLeft, &lt;span style="color: #006080"&gt;"20px"&lt;/span&gt;);
    mapType.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(65, UnitType.Pixel);

    &lt;span style="color: #008000"&gt;//Set the Zoom TextBox properties&lt;/span&gt;
    zoom.Style.Add(System.Web.UI.HtmlTextWriterStyle.MarginLeft, &lt;span style="color: #006080"&gt;"20px"&lt;/span&gt;);
    zoom.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(65, UnitType.Pixel);

    &lt;span style="color: #008000"&gt;//Set the latitude label properties&lt;/span&gt;
    lLat.Text = &lt;span style="color: #006080"&gt;"Latitude"&lt;/span&gt;;
    lLat.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(60, UnitType.Pixel);
    lLat.Style.Add(&lt;span style="color: #006080"&gt;"float"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"left"&lt;/span&gt;);

    &lt;span style="color: #008000"&gt;//Set the longitude label properties&lt;/span&gt;
    lLong.Text = &lt;span style="color: #006080"&gt;"Longitude"&lt;/span&gt;;
    lLong.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(60, UnitType.Pixel);
    lLong.Style.Add(&lt;span style="color: #006080"&gt;"float"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"left"&lt;/span&gt;);

    &lt;span style="color: #008000"&gt;//Set the map type label properties&lt;/span&gt;
    lMapType.Text = &lt;span style="color: #006080"&gt;"Map Type"&lt;/span&gt;;
    lMapType.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(60, UnitType.Pixel);
    lMapType.Style.Add(&lt;span style="color: #006080"&gt;"float"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"left"&lt;/span&gt;);

    &lt;span style="color: #008000"&gt;//Set the postcode label properties&lt;/span&gt;
    lPost.Text = &lt;span style="color: #006080"&gt;"Post Code"&lt;/span&gt;;
    lPost.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(60, UnitType.Pixel);
    lPost.Style.Add(&lt;span style="color: #006080"&gt;"float"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"left"&lt;/span&gt;);

    &lt;span style="color: #008000"&gt;//Set the zoom label properties&lt;/span&gt;
    lZoom.Text = &lt;span style="color: #006080"&gt;"Zoom"&lt;/span&gt;;
    lZoom.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(60, UnitType.Pixel);
    lZoom.Style.Add(&lt;span style="color: #006080"&gt;"float"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"left"&lt;/span&gt;);
                    
    &lt;span style="color: #008000"&gt;//Set the button properties&lt;/span&gt;
    btn.Text = &lt;span style="color: #006080"&gt;"Look Up"&lt;/span&gt;;
    
    &lt;span style="color: #008000"&gt;//Set the map canvas&lt;/span&gt;
    Div.ID = &lt;span style="color: #006080"&gt;"mapDiv"&lt;/span&gt;;
    Div.Style.Add(System.Web.UI.HtmlTextWriterStyle.MarginTop, &lt;span style="color: #006080"&gt;"20px"&lt;/span&gt;);
    Div.Width = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(400, UnitType.Pixel);
    Div.Height = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Unit(400, UnitType.Pixel);

    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ApplyControlAttributes(latitiude);
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ApplyControlAttributes(longitude);
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ApplyControlAttributes(zoom);

    &lt;span style="color: #008000"&gt;//Add the controls to the controls collection&lt;/span&gt;
    Controls.Add(lPost);
    Controls.Add(txtPostCode);
    Controls.Add(btn);
    Controls.Add(brk1);
    Controls.Add(lLat);
    Controls.Add(latitiude);
    Controls.Add(brk2);
    Controls.Add(lLong);
    Controls.Add(longitude);
    Controls.Add(brk3);
    Controls.Add(lZoom);
    Controls.Add(zoom);
    Controls.Add(brk4);
    Controls.Add(lMapType);
    Controls.Add(mapType);
    Controls.Add(Div);

    &lt;span style="color: #008000"&gt;//Add the JavaScript required to render the google map&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!Page.ClientScript.IsClientScriptIncludeRegistered(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(CoordinatePropertyControl), &lt;span style="color: #006080"&gt;"MAP"&lt;/span&gt;))
        Page.ClientScript.RegisterClientScriptBlock(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(CoordinatePropertyControl), &lt;span style="color: #006080"&gt;"MAP"&lt;/span&gt;, 
            &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(JAVASCRIPT,
            WebConfigurationManager.AppSettings[&lt;span style="color: #006080"&gt;"GoogleMapKey"&lt;/span&gt;], &lt;span style="color: #008000"&gt;//0&lt;/span&gt;
            WebConfigurationManager.AppSettings[&lt;span style="color: #006080"&gt;"GoogleMapKey"&lt;/span&gt;], &lt;span style="color: #008000"&gt;//1&lt;/span&gt;
            latitiude.ClientID, &lt;span style="color: #008000"&gt;//2&lt;/span&gt;
            longitude.ClientID, &lt;span style="color: #008000"&gt;//3&lt;/span&gt;
            &lt;span style="color: #006080"&gt;""&lt;/span&gt;, &lt;span style="color: #008000"&gt;//4&lt;/span&gt;
            Div.ClientID, &lt;span style="color: #008000"&gt;//5&lt;/span&gt;
            zoom.ClientID, &lt;span style="color: #008000"&gt;//6&lt;/span&gt;
            mapType.ClientID, &lt;span style="color: #008000"&gt;//7&lt;/span&gt;
            PropertyData.Name &lt;span style="color: #008000"&gt;//8&lt;/span&gt;
            ));

    &lt;span style="color: #008000"&gt;//Add the onclick javascript to the postcode&lt;/span&gt;
    &lt;span style="color: #008000"&gt;//lookup button&lt;/span&gt;
    btn.Attributes.Add(&lt;span style="color: #006080"&gt;"onclick"&lt;/span&gt;, 
        &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;"usePointFromPostcode(document.getElementById('{0}').value, placeMarkerAtPoint); return false;"&lt;/span&gt;,
        txtPostCode.ClientID));

    &lt;span style="color: #008000"&gt;//Make the map type and zoom textboxes&lt;/span&gt;
    &lt;span style="color: #008000"&gt;//readonly as they are set by the google&lt;/span&gt;
    &lt;span style="color: #008000"&gt;//map control.&lt;/span&gt;
    zoom.Attributes.Add(&lt;span style="color: #006080"&gt;"readonly"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"true"&lt;/span&gt;);
    mapType.Attributes.Add(&lt;span style="color: #006080"&gt;"readonly"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"true"&lt;/span&gt;);

    &lt;span style="color: #008000"&gt;//Lastly populate the edit controls with values from the underlying CoordinateProperty&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SetupEditControls();
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;With that done we need to override the method which will populate the edit controls with values from the underlying CoordinateProperty (either default of from the database)&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// Inherited. Initialize the value of the TextBox control.&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SetupEditControls()
{
    &lt;span style="color: #008000"&gt;//Set the zoom and map type textbox values&lt;/span&gt;
    zoom.Text = CoordinateProperty.Zoom.ToString();
    mapType.Text = CoordinateProperty.MapType;

    &lt;span style="color: #008000"&gt;//If the Latitude/Longitude have values set the relevant&lt;/span&gt;
    &lt;span style="color: #008000"&gt;//textbox properties and add the GoogleMap Javascript&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (CoordinateProperty.Latitude.HasValue &amp;amp;&amp;amp; CoordinateProperty.Longitude.HasValue)
    {
        latitiude.Text = CoordinateProperty.Latitude.Value.ToString();
        longitude.Text = CoordinateProperty.Longitude.Value.ToString();

        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!Page.ClientScript.IsStartupScriptRegistered(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(CoordinatePropertyControl), 
            &lt;span style="color: #006080"&gt;"EXISTING"&lt;/span&gt;))
        {
            Page.ClientScript.RegisterStartupScript(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(CoordinatePropertyControl), 
                &lt;span style="color: #006080"&gt;"EXISTING"&lt;/span&gt;,
                &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(EXISTING,
                    latitiude.Text,
                    longitude.Text,
                    zoom.Text));
        }
    }
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Finally we must override the method which sets the value of the underlying CoordinateProperty with values entered in the UI by the user:&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// Inherited. Applies changes for the posted data to the page's properties when the RenderType property&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// is set to Edit.&lt;/span&gt;
&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ApplyEditChanges()
{
    &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.SetValue(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(CultureInfo.InvariantCulture, &lt;span style="color: #006080"&gt;"{0},{1},{2},{3}"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.latitiude.Text, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.longitude.Text, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.zoom.Text, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.mapType.Text));
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And that's it - put it all together and you'll be able to configure a Google Map 'widget' in EPiServer.&lt;/p&gt;

&lt;p&gt;Oh - one small thing to note - the above JavaScript will only allow for ONE &lt;em&gt;CoordinateProperty&lt;/em&gt; to be added to a &lt;em&gt;PageType&lt;/em&gt;. If you add more than one to the same &lt;em&gt;PageType&lt;/em&gt; it will break. If I get time I'll change it, but our current requirement is only for one map per page - sorry!&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/brad/aggbug/309.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brad</dc:creator>
            <guid>http://blogs.interakting.co.uk/brad/archive/2008/06/09/C-Google-Map-Server-Control---Part-2---Custom.aspx</guid>
            <pubDate>Mon, 09 Jun 2008 09:24:21 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/brad/comments/309.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/brad/archive/2008/06/09/C-Google-Map-Server-Control---Part-2---Custom.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/brad/comments/commentRss/309.aspx</wfw:commentRss>
        </item>
        <item>
            <title>C#: Google Map Server Control - Part 1</title>
            <link>http://blogs.interakting.co.uk/brad/archive/2008/06/06/C-Google-Map-Server-Control---Part-1.aspx</link>
            <description>&lt;p&gt;Following on from my Google Analytics server control, I wanted make something "cooler", so creating a Server Control to render a Google Map control seemed ideal. Part 1 covers the creation of the this control, stay tuned for &lt;a title="Read part two here" href="http://blogs.interakting.co.uk/brad/archive/2008/06/09/C-Google-Map-Server-Control---Part-2---Custom.aspx" target="_blank"&gt;part 2&lt;/a&gt; which will focus on creating a custom EPiServer property so it can be used in the EPiServer edit area, featuring Geocoding to lookup the coordinates from a UK post code, Map type selection and zoom level. &lt;/p&gt;  &lt;p&gt;Anyway here's the generic bit that can be used on any site...&lt;/p&gt;  &lt;p&gt;First off we need a set of basic properties to hold Latitude, Longitude, Zoom Level and Map Type:&lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; height: 238px; background-color: #f4f4f4"&gt;   &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; Latitude
{
    get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; GetPropertyValue(&lt;span style="color: #006080"&gt;"Latitude"&lt;/span&gt;, (&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;)0); }
    set { SetPropertyValue(&lt;span style="color: #006080"&gt;"Latitude"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;); }
}
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; Longitude
{
    get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; GetPropertyValue(&lt;span style="color: #006080"&gt;"Longitude"&lt;/span&gt;, (&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;)0); }
    set { SetPropertyValue(&lt;span style="color: #006080"&gt;"Longitude"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;); }
}
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Zoom
{
    get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; GetPropertyValue(&lt;span style="color: #006080"&gt;"Zoom"&lt;/span&gt;, 5); }
    set { SetPropertyValue(&lt;span style="color: #006080"&gt;"Zoom"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;); }
}
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; MapType
{
    get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; GetPropertyValue(&lt;span style="color: #006080"&gt;"MapType"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"Map"&lt;/span&gt;); }
    set { SetPropertyValue(&lt;span style="color: #006080"&gt;"MapType"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;); }
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next come's the rather complex looking JavaScript code. I've done it so that it will allow multiple controls to be placed on the same page. IMPORTANT: Make sure you {0} in &lt;em&gt;COMMONJAVASCRIPT &lt;/em&gt;is your unique Google Maps/API Key, which is generated on a per domain basis.&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; COMMONJAVASCRIPT = &lt;span style="color: #006080"&gt;@"
        &amp;lt;script src="&lt;/span&gt;&lt;span style="color: #006080"&gt;"http://maps.google.com/maps?file=api&amp;amp;amp;v=2&amp;amp;amp;key={0}"&lt;/span&gt;&lt;span style="color: #006080"&gt;" type="&lt;/span&gt;&lt;span style="color: #006080"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color: #006080"&gt;"&amp;gt;&amp;lt;/script&amp;gt;
        &amp;lt;script src="&lt;/span&gt;&lt;span style="color: #006080"&gt;"http://www.google.com/uds/api?file=uds.js&amp;amp;amp;v=1.0&amp;amp;amp;key={0}"&lt;/span&gt;&lt;span style="color: #006080"&gt;" type="&lt;/span&gt;&lt;span style="color: #006080"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color: #006080"&gt;"&amp;gt;&amp;lt;/script&amp;gt;"&lt;/span&gt;;
        
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; JAVASCRIPT = &lt;span style="color: #006080"&gt;@"
        &amp;lt;script type="&lt;/span&gt;&lt;span style="color: #006080"&gt;"text/javascript"&lt;/span&gt;&lt;span style="color: #006080"&gt;"&amp;gt;
        function GoogleMapLoad{6}() {{
          if (GBrowserIsCompatible()) {{
            var map = new GMap2(document.getElementById("&lt;/span&gt;&lt;span style="color: #006080"&gt;"{3}"&lt;/span&gt;&lt;span style="color: #006080"&gt;"));
        
                if("&lt;/span&gt;&lt;span style="color: #006080"&gt;"{5}"&lt;/span&gt;&lt;span style="color: #006080"&gt;" == "&lt;/span&gt;&lt;span style="color: #006080"&gt;"Hybrid"&lt;/span&gt;&lt;span style="color: #006080"&gt;")
                   map.setCenter(new GLatLng({1},{2}), parseInt({4}), G_HYBRID_MAP);
                else if("&lt;/span&gt;&lt;span style="color: #006080"&gt;"{5}"&lt;/span&gt;&lt;span style="color: #006080"&gt;" == "&lt;/span&gt;&lt;span style="color: #006080"&gt;"Satellite"&lt;/span&gt;&lt;span style="color: #006080"&gt;")
                   map.setCenter(new GLatLng({1},{2}), parseInt({4}), G_SATELLITE_MAP);
                else
                   map.setCenter(new GLatLng({1},{2}), parseInt({4}), G_NORMAL_MAP);
                
                var point = new GLatLng({1},{2});
                map.addOverlay(new GMarker(point));
                map.addControl(new GMapTypeControl());
                map.addControl(new GLargeMapControl());
            }}
        }}
        &amp;lt;/script&amp;gt;"&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next we need to override the default tag that the server control would typically render (span) with a div, so that the Google map has a "canvas".&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;//Google map must be rendered inside a &amp;lt;DIV&amp;gt; tag, so we'll override the default &amp;lt;SPAN&amp;gt;.&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; HtmlTextWriterTag TagKey
{
    get
    {
        &lt;span style="color: #008000"&gt;//Return DIV not SPAN&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; HtmlTextWriterTag.Div;
    }
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And last but not least, the overloaded &lt;em&gt;CreateChildControls()&lt;/em&gt;. Firstly we check to see if there are (valid) Latitude and longitude values, if there is we register two blocks of JavaScript. Notice the second block's key includes the controls ID - which allows multiple maps to be used on the same page. The first 'common' block will only be registered once regardless of how many maps on the page. The second block has five strings passed to it which include the Google API Key (stored in the AppSettings) the control's ClientID (so the map's canvas can be accessed) along with the lat/lng/zoom etc.&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CreateChildControls()
{
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Latitude != 0 &amp;amp;&amp;amp; Longitude != 0)
    {
        &lt;span style="color: #008000"&gt;//Check if the COMMON google map javascript block has been registered&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!Page.ClientScript.IsClientScriptBlockRegistered(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(GoogleMap), &lt;span style="color: #006080"&gt;"GoogleMap"&lt;/span&gt;))
            Page.ClientScript.RegisterClientScriptBlock(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(GoogleMap), &lt;span style="color: #006080"&gt;"GoogleMap"&lt;/span&gt;, COMMONJAVASCRIPT);

        &lt;span style="color: #008000"&gt;//Check if the google map javascript block for THIS map has been registered&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!Page.ClientScript.IsClientScriptBlockRegistered(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(GoogleMap), &lt;span style="color: #006080"&gt;"GoogleMap"&lt;/span&gt; + ID))
            Page.ClientScript.RegisterClientScriptBlock(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(GoogleMap), &lt;span style="color: #006080"&gt;"GoogleMap"&lt;/span&gt; + ID, 
                &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(CultureInfo.InvariantCulture, JAVASCRIPT,
                        WebConfigurationManager.AppSettings[&lt;span style="color: #006080"&gt;"GoogleMapKey"&lt;/span&gt;], &lt;span style="color: #008000"&gt;//0&lt;/span&gt;
                        Latitude,  &lt;span style="color: #008000"&gt;//1&lt;/span&gt;
                        Longitude, &lt;span style="color: #008000"&gt;//2&lt;/span&gt;
                        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ClientID, &lt;span style="color: #008000"&gt;//3&lt;/span&gt;
                        Zoom, &lt;span style="color: #008000"&gt;// 4&lt;/span&gt;
                        MapType, &lt;span style="color: #008000"&gt;//5&lt;/span&gt;
                        ClientID &lt;span style="color: #008000"&gt;//6), &lt;/span&gt;
                    &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);

        &lt;span style="color: #008000"&gt;//Now we need to add the google maps onload JavaScript function for THIS MAP ONLY (it its not be added already)&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!Page.ClientScript.IsStartupScriptRegistered(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(GoogleMap), &lt;span style="color: #006080"&gt;"GoogleMapLoad"&lt;/span&gt; + ID))
            Page.ClientScript.RegisterStartupScript(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(GoogleMap), &lt;span style="color: #006080"&gt;"GoogleMapLoad"&lt;/span&gt; + ID, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;"GoogleMapLoad{0}();"&lt;/span&gt;, ClientID), &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);

        &lt;span style="color: #008000"&gt;//Now we need to add the google maps onUNload JavaScript function (it its not be added already)&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!Page.ClientScript.IsStartupScriptRegistered(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(GoogleMap), &lt;span style="color: #006080"&gt;"GoogleMapUnload"&lt;/span&gt;))
            Page.ClientScript.RegisterStartupScript(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(GoogleMap), &lt;span style="color: #006080"&gt;"GoogleMapUnload"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"window.onunload = function () { GUnload(); };"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);
    }
    &lt;span style="color: #008000"&gt;//now call the base controls Create Child Controls&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.CreateChildControls();
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;UPDATED:&lt;/strong&gt; Check out &lt;a href="http://blogs.interakting.co.uk/brad/archive/2008/06/09/C-Google-Map-Server-Control---Part-2---Custom.aspx" target="_blank"&gt;part 2&lt;/a&gt; for how to use this with EPiServer.&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/brad/aggbug/308.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brad</dc:creator>
            <guid>http://blogs.interakting.co.uk/brad/archive/2008/06/06/C-Google-Map-Server-Control---Part-1.aspx</guid>
            <pubDate>Fri, 06 Jun 2008 15:17:03 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/brad/comments/308.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/brad/archive/2008/06/06/C-Google-Map-Server-Control---Part-1.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/brad/comments/commentRss/308.aspx</wfw:commentRss>
        </item>
        <item>
            <title>ASP.NET: Event Log in IIS6/Server 2003</title>
            <link>http://blogs.interakting.co.uk/brad/archive/2008/03/06/ASP.NET-Event-Log-in-IIS6Server-2003.aspx</link>
            <description>&lt;p&gt;If you want to write to the Server's Event log from ASP.NET you'll first need to tweak some security settings. The first change is easy, however the second took me a while to find.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step One:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Grant "Full Control" to the "IIS_WPG" group to the following registry key:&lt;/p&gt;  &lt;div class="csharpcode-wrapper" style="width: 97.5%; height: 39px"&gt;   &lt;pre class="csharpcode"&gt;HKLM\SYSTEM\CurrentControlSet\Services\EventLog&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step Two:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the security restrictions added to IIS 6 under Windows Server 2003 was much tighter ACLs (Access Control Lists) on the event logs. This restricts what accounts can read and write to the logs (application, system &amp;amp; security). To overcome this you'll need to add the following value. Incase you're worried what security hole I'm opening up for you there's a breakdown of what it means at the end of the post.&lt;/p&gt;

&lt;div class="csharpcode-wrapper" style="width: 97.5%; height: 47px"&gt;
  &lt;pre class="csharpcode"&gt;(A;;0x0002;;;AU)&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Add the above value to the end of the existing "CustomSD" value found at following path (pick relevant one):&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;pre class="csharpcode" style="width: 97.5%; height: 92px"&gt;&lt;p&gt;HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application&lt;/p&gt;&lt;p&gt;HKLM\SYSTEM\CurrentControlSet\Services\EventLog\System&lt;/p&gt;&lt;p&gt;HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Security&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So mine went from:&lt;/p&gt;

&lt;div class="csharpcode-wrapper" style="width: 97.5%; height: 39px"&gt;
  &lt;pre class="csharpcode"&gt;O:BAG:SYD:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;to: (scroll to all the way to the right to see the change in bold):&lt;/p&gt;

&lt;div class="csharpcode-wrapper" style="width: 97.5%; height: 41px"&gt;
  &lt;pre class="csharpcode"&gt;O:BAG:SYD:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)&lt;strong&gt;(A;;0x0002;;;AU)&lt;/strong&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The value being added is written in Security Descriptor Definition Language (SDDL) and is as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A = Access allowed. &lt;/li&gt;

  &lt;li&gt;;; = token delimiter (don't know why there's two of them?) &lt;/li&gt;

  &lt;li&gt;0x0002 = Permission to write log files. &lt;/li&gt;

  &lt;li&gt;;;; = token delimiter (again - don't know why there's three of them?) &lt;/li&gt;

  &lt;li&gt;AU = Authenticated Users. &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://blogs.interakting.co.uk/brad/aggbug/218.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brad</dc:creator>
            <guid>http://blogs.interakting.co.uk/brad/archive/2008/03/06/ASP.NET-Event-Log-in-IIS6Server-2003.aspx</guid>
            <pubDate>Thu, 06 Mar 2008 11:44:24 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/brad/comments/218.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/brad/archive/2008/03/06/ASP.NET-Event-Log-in-IIS6Server-2003.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/brad/comments/commentRss/218.aspx</wfw:commentRss>
        </item>
        <item>
            <title>ASP.NET: Embed Images/JavaScript in a dll</title>
            <link>http://blogs.interakting.co.uk/brad/archive/2008/01/31/ASP.NET-Embed-ImagesJavaScript-in-a-dll.aspx</link>
            <description>&lt;p&gt;Its good practice to separate out code that can be re-used into its own class library which can easy be referenced by other projects. Until now any resources such as images/JavaScript files that I'd created I needed to remember to copy to each web site that used the dll, ensuring that I created the correct directory structure so the paths would be correct. Then it dawned on me that you must be able to embed these files into the dll itself. Here's the steps I used to embed an image file for a AjaxControlTookit Calendar Extender that I was using in a custom server control (the same principle can be applied to any file you need - typically JavasScript and/or images will be embedded)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Add your file to the Class Library project&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;(in my example I added [PROJECT ROOT]/Resources/Calendar.png")&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Select the newly added file and in the Properties window select:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Build Action = "Embedded Resource";&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In the Project's AssemblyInfo.cs file add the following line:&lt;/p&gt;  &lt;div class="csharpcode-wrapper" style="width: 97.5%; height: 135px"&gt;   &lt;pre class="csharpcode" style="width: 97.5%; height: 119px"&gt;&lt;span class="rem"&gt;//Replace "BradsNamespace" with the namespace of your project&lt;/span&gt;
&lt;span class="rem"&gt;//Replace "Resources" with the folder structure from the root of the project &lt;br /&gt;//to the file (using . instead of / )&lt;/span&gt;
&lt;span class="rem"&gt;//Replace "Calendar.png" with your file's name &lt;/span&gt;
&lt;span class="rem"&gt;//Replace "img/png" with relevant type e.g. "text/javascript", "image/jpeg" etc&lt;/span&gt;
[assembly: System.Web.UI.WebResource(&lt;br /&gt;    &lt;span class="str"&gt;"BradsNamespace.Resources.Calendar.png"&lt;/span&gt;, &lt;span class="str"&gt;"img/png"&lt;/span&gt;)]&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now retrieve the Url for the file:&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;pre class="csharpcode" style="width: 97.5%; height: 96px"&gt;Image CalendarImage = &lt;span class="kwrd"&gt;new&lt;/span&gt; Image();

CalendarImage.ImageUrl = Page.ClientScript.GetWebResourceUrl(
 &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetType(),
 &lt;span class="rem"&gt;//Replace following with the string entered in AssemblyInfo.cs&lt;/span&gt;
 &lt;span class="str"&gt;"BradsNamespace.Resources.Calendar.png"&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Finished:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And that's it! Now when you run it &lt;a title="Microsoft .NET " href="http://msdn.microsoft.com/netframework/" target="_blank"&gt;.NET&lt;/a&gt; will generate the Url for you in the format:&lt;/p&gt;

&lt;div class="csharpcode-wrapper" style="width: 97.5%; height: 32px"&gt;
  &lt;pre class="csharpcode"&gt;src="/WebResource.axd?d=_Y_kbnu3Fp4-fBKDGxpOa-LgnKcgPOIASf1ExUjshsj3373650125705280" &lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://blogs.interakting.co.uk/brad/aggbug/195.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brad</dc:creator>
            <guid>http://blogs.interakting.co.uk/brad/archive/2008/01/31/ASP.NET-Embed-ImagesJavaScript-in-a-dll.aspx</guid>
            <pubDate>Thu, 31 Jan 2008 08:42:57 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/brad/comments/195.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/brad/archive/2008/01/31/ASP.NET-Embed-ImagesJavaScript-in-a-dll.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/brad/comments/commentRss/195.aspx</wfw:commentRss>
        </item>
        <item>
            <title>AJAX: FileUpload control inside an UpdatePanel</title>
            <link>http://blogs.interakting.co.uk/brad/archive/2008/01/23/AJAX-FileUpload-control-inside-an-UpdatePanel.aspx</link>
            <description>&lt;p&gt;UpdatePanels work fine with almost all controls, one control that it does 'break' however is FileUpload. If you try and upload a file it will seem to work - but if you check FileUpload.HasFile it will always return false. Rubbish if you've got an UpdatePanel in your MasterPage! However there is a solution, in fact it's not the UpdatePanel that breaks it, but the asynchronous PostBack instead. So a neat trick is to register the button you're using to cause the upload to use a normal PostBack. This can be done as follows:&lt;/p&gt;  &lt;div class="csharpcode-wrapper"&gt;   &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;this&lt;/span&gt;.ScriptManager.RegisterPostBackControl(btnUpload);&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Then when the user clicks the upload button they'll get a normal PostBack (and therefore an uploaded file), while all the other controls on the page will continue to operate asynchronously - no need to re-jig the whole layout of the site.&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/brad/aggbug/185.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brad</dc:creator>
            <guid>http://blogs.interakting.co.uk/brad/archive/2008/01/23/AJAX-FileUpload-control-inside-an-UpdatePanel.aspx</guid>
            <pubDate>Wed, 23 Jan 2008 21:53:31 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/brad/comments/185.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/brad/archive/2008/01/23/AJAX-FileUpload-control-inside-an-UpdatePanel.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/brad/comments/commentRss/185.aspx</wfw:commentRss>
        </item>
        <item>
            <title>AJAX: DataBinding Issue</title>
            <link>http://blogs.interakting.co.uk/brad/archive/2008/01/16/174.aspx</link>
            <description>&lt;p&gt;I've just spent a while pulling my hair out trying to find out why some text in my repeater control wasn't updating after postback on one page but was on another. The repeater was in a UserControl I'd made, and the same control was on both pages - the only difference - once was inside an &lt;a title="Microsoft ASP.NET AJAX" href="http://www.asp.net/ajax/" target="_blank"&gt;AJAX&lt;/a&gt; UpdatePanel and on the other page it wasn't. &lt;/p&gt;  &lt;p&gt;Here's the offending code:&lt;/p&gt;  &lt;div class="csharpcode-wrapper"&gt;   &lt;pre class="csharpcode"&gt;&amp;lt;ItemTemplate&amp;gt;
    &amp;lt;tr&amp;gt;
       &amp;lt;td&amp;gt;&amp;lt;asp:Image runat=&lt;span class="str"&gt;"server"&lt;/span&gt; ImageUrl=&lt;span class="str"&gt;'&amp;lt;%# Eval("Image") "%&amp;gt;'&lt;/span&gt; ID=&lt;span class="str"&gt;"iImage"&lt;/span&gt; /&amp;gt;&amp;lt;/td&amp;gt;
       &amp;lt;td&amp;gt;&amp;lt;%# Eval(&lt;span class="str"&gt;"Score"&lt;/span&gt;) %&amp;gt;&amp;lt;/td&amp;gt;
       &amp;lt;td&amp;gt;&amp;lt;%# Eval(&lt;span class="str"&gt;"Percentage"&lt;/span&gt;) %&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
&amp;lt;/ItemTemplate&amp;gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now what was strange is that the image was updating ok (this confused me a lot while viewing it as the image is a bar representing the percentage figure and i spent ages working out while the image was wrong - before i noticed that it was the figure that was wrong not the image!)&lt;/p&gt;

&lt;p&gt;Once I changed it to the following it worked fine:&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;pre class="csharpcode"&gt;&amp;lt;ItemTemplate&amp;gt;
    &amp;lt;tr&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;asp:Image runat=&lt;span class="str"&gt;"server"&lt;/span&gt; ImageUrl=&lt;span class="str"&gt;'&amp;lt;%# Eval("Image") "%&amp;gt;'&lt;/span&gt; ID=&lt;span class="str"&gt;"iImage"&lt;/span&gt; /&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;asp:Literal runat=&lt;span class="str"&gt;"server"&lt;/span&gt; Text=&lt;span class="str"&gt;'&amp;lt;%# Eval("Score") %&amp;gt;'&lt;/span&gt; ID=&lt;span class="str"&gt;"lScore"&lt;/span&gt; /&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;asp:Literal runat=&lt;span class="str"&gt;"server"&lt;/span&gt; Text=&lt;span class="str"&gt;'&amp;lt;%# Eval("Percentage") %&amp;gt;'&lt;/span&gt; ID=&lt;span class="str"&gt;"lPercent"&lt;/span&gt; /&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
&amp;lt;/ItemTemplate&amp;gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The page that wasn't working contained an UpdatePanel holding a Dropdown box that causes my UserControl to rebind its Repeater control... Does anyone know why rebinding in the standard page works in a normal postback but not when inside an &lt;a title="Microsoft ASP.NET AJAX" href="http://www.asp.net/ajax/" target="_blank"&gt;AJAX&lt;/a&gt; UpdatePanel?&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/brad/aggbug/174.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brad</dc:creator>
            <guid>http://blogs.interakting.co.uk/brad/archive/2008/01/16/174.aspx</guid>
            <pubDate>Wed, 16 Jan 2008 17:22:30 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/brad/comments/174.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/brad/archive/2008/01/16/174.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/brad/comments/commentRss/174.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Firefox: Using an FCKeditor in an AJAX UpdatePanel</title>
            <link>http://blogs.interakting.co.uk/brad/archive/2008/01/14/162.aspx</link>
            <description>&lt;p&gt;I've been using the &lt;a title="Microsoft .NET " href="http://msdn.microsoft.com/netframework/" target="_blank"&gt;.NET&lt;/a&gt; version of &lt;a title="FCKeditor" href="http://www.fckeditor.net/" target="_blank"&gt;FCKeditor&lt;/a&gt; for some time, but recently changed the page layout, resulting in the &lt;a title="FCKeditor" href="http://www.fckeditor.net/" target="_blank"&gt;FCKeditor&lt;/a&gt; instance now residing in an &lt;a title="Microsoft ASP.NET AJAX" href="http://www.asp.net/ajax/" target="_blank"&gt;AJAX&lt;/a&gt; UpdatePanel. All was fine while using IE, but when I tested it in &lt;a title="Firefox" href="http://www.mozilla-europe.org/en/products/firefox/" target="_blank"&gt;Firefox&lt;/a&gt; I noticed that the changed content in the &lt;a title="FCKeditor" href="http://www.fckeditor.net/" target="_blank"&gt;FCKeditor&lt;/a&gt; wasn't getting saved to the database. It turns out its a JavaScript issue that effects &lt;a title="Firefox" href="http://www.mozilla-europe.org/en/products/firefox/" target="_blank"&gt;Firefox&lt;/a&gt; and Safari.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;I've been unable to find the perfect solution but in the meantime I discovered the following code does the trick - but unfortunately causes &lt;a title="Firefox" href="http://www.mozilla-europe.org/en/products/firefox/" target="_blank"&gt;Firefox&lt;/a&gt;/Safari users to see a full post back - not just what's in the UpdatePanel.&lt;/p&gt;  &lt;div class="csharpcode-wrapper"&gt;   &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (Request.Browser.Browser.ToLower().Contains(&lt;span class="str"&gt;"firefox"&lt;/span&gt;) || Request.Browser.Browser.ToLower().Contains(&lt;span class="str"&gt;"safari"&lt;/span&gt;))
        {
            ScriptManager sm = Master.FindControl(&lt;span class="str"&gt;"ScriptManager1"&lt;/span&gt;) &lt;span class="kwrd"&gt;as&lt;/span&gt; ScriptManager;
            sm.RegisterPostBackControl(btnMySubmitButton);
        }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If anyone knows a better way to fix it please let me know!&lt;/p&gt;&lt;img src="http://blogs.interakting.co.uk/brad/aggbug/162.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brad</dc:creator>
            <guid>http://blogs.interakting.co.uk/brad/archive/2008/01/14/162.aspx</guid>
            <pubDate>Mon, 14 Jan 2008 14:50:00 GMT</pubDate>
            <wfw:comment>http://blogs.interakting.co.uk/brad/comments/162.aspx</wfw:comment>
            <comments>http://blogs.interakting.co.uk/brad/archive/2008/01/14/162.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.interakting.co.uk/brad/comments/commentRss/162.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>