Links to the other posts in this series
This really is turning into a bit of a marathon - sorry about that. Here's the full source for my implementation of the VEMapControl (without any embedded resources - we'll get to that!):
using System; using System.Web.UI; using System.Web.UI.WebControls; using System.Collections.Generic; namespace ServerControls { public class VEMapControl : CompositeControl, IScriptControl { protected Image i = new Image(); protected Panel p = new Panel(); public VEMapControl() { this.Height = 150; this.Width = 150; this.Style.Add(HtmlTextWriterStyle.Position, "Relative"); this.Style.Add(HtmlTextWriterStyle.Margin, "5px"); this.Style.Add(HtmlTextWriterStyle.Padding, "1px"); } protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.Div; } } public string ImageUrl { get { EnsureChildControls(); return i.ImageUrl; } set { EnsureChildControls(); i.ImageUrl = value; } } protected override void CreateChildControls() { p.ID = this.ID; p.Style.Add(HtmlTextWriterStyle.Position, "Relative"); p.Style.Add(HtmlTextWriterStyle.Width, "80%"); p.Style.Add(HtmlTextWriterStyle.Height, "80%"); p.Style.Add(HtmlTextWriterStyle.Margin, "10% 10%"); p.Style.Add(HtmlTextWriterStyle.Left, "0"); p.Style.Add(HtmlTextWriterStyle.Top, "0"); i.Style.Add(HtmlTextWriterStyle.Position, "Absolute"); i.Style.Add(HtmlTextWriterStyle.Width, "100%"); i.Style.Add(HtmlTextWriterStyle.Height, "100%"); i.Style.Add(HtmlTextWriterStyle.Left, "0"); i.Style.Add(HtmlTextWriterStyle.Top, "0"); this.Controls.Add(p); this.Controls.Add(i); } public double Lat { get { return (double)(ViewState["Lat"] ?? 0.0); } set { ViewState["Lat"] = value; } } public double Lon { get { return (double)(ViewState["Lon"] ?? 0.0); } set { ViewState["Lon"] = value; } } public IEnumerable<ScriptDescriptor> GetScriptDescriptors() { ScriptControlDescriptor scd = new ScriptControlDescriptor("ServerControls.VEMapControl", this.ClientID); scd.AddProperty("lat", this.Lat); scd.AddProperty("lon", this.Lon); yield return scd; } public IEnumerable<ScriptReference> GetScriptReferences() { yield return new ScriptReference("~/JavaScript/VEMapControl.js"); yield return new ScriptReference("http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6"); } #region Extra Stuff Because We Implement IScriptControl / IExtenderControl protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); ScriptManager sm = ScriptManager.GetCurrent(this.Page); if (sm == null) { throw new InvalidOperationException("A ScriptManager is required"); } sm.RegisterScriptControl(this); } protected override void Render(HtmlTextWriter writer) { base.Render(writer); ScriptManager.GetCurrent(this.Page).RegisterScriptDescriptors(this); } #endregion } }
Let's take a look at a few aspects:
The above in conjunction with the appropriate VEMapControl.js script allows me to use it in a page:
<%@ Page Language="C#" %> <%@ Register Assembly="ServerControls" Namespace="ServerControls" TagPrefix="cc1" %> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <cc1:VEMapControl ID="VEMapControl1" runat="server" Lat="51.52514" Lon="-0.733681" ImageUrl="~/Photos/Image1.png" Height="250" Width="250" /> </div> </form> </body> </html>
Which generates the following result:
Next we'll look at embedding resources in the assembly so we're not referencing "loose" scripts on the server. We can also include our own custom pushpin icon in this fashion.
PingBack from http://blogs.msdn.com/mikeormond/archive/2008/03/28/building-asp-net-ajax-controls-index-post.aspx
seriously informative + cool series!
Great series. Thanks for the indepth information.
Links to the other posts in this series In Part 7 we looked at how to wrap our client components into