Link to home
Create AccountLog in
Avatar of Nugs
Nugs

asked on

Custom Control Basics

This is my first attempt at building a custom control. I have the basics of it working. The control renders some JavaScript blocks and some HTML onto the page it is added to.

I would now like to be able to pass in values to the custom control on Page_Load (or whatever) of the page rendering the control.

My control uses the protected override void OnPreRender(EventArgs e) to do allot of the Javscript rendering. I have tried to build properties in the control to accept values but i am having trouble getting the page to load these variable into the control before it is rendered on the page.

My understand of how this works is nonexistent. So i guess i am asking for a good resource of information on building Custom Controls that can be "set" from the page loading it.

Nugs
Avatar of lambdabunker
lambdabunker
Flag of Australia image

when you say custom controls are you talking about UserControls.?
ASKER CERTIFIED SOLUTION
Avatar of Ramuncikas
Ramuncikas
Flag of Lithuania image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
Avatar of Nugs
Nugs

ASKER

Ramuncikas:

That has to be the best explanation of a topic i have ever gotten on EE on the first round. If you don't mind i am going to rack your brain a little more on this.

I think i need to explain what this control will be doing exactly. And to confirm, my control is a stand alone class. I have it build and working and i have the page loading and displaying something currently. It is the intricacies of how these controls work that is really stopping me moving forward with it faster. How it uses the viewstate is something i never knew (Starting to make more sense now).

So let me get right down to it... This control will be used as a wrapper for GoogleMaps API which is Javascript based. I have been searching the web for a .net version of the api. I did find some control that i could purchase that would do what i am wanting and then i found this: http://www.codeproject.com/KB/custom-controls/LatLaysFlat-Part1.aspx

Bill Pierce created a custom control that would render the Javascript to the page loading his control. His control is a little more than i want and does some things that we do not want to do, additionally there are some things that i would like to do that are not included. But the idea is the same. Plus it is a project i would like to dive into myself as i have not had much exposure to it.

So i want to build a custom control that can be added to any website and will render the Google Map on the page loading it. I want the control to accept a number of different parameter to "set the control up" before rendering it. After it is rendered it will not do much via the control (the javascript that was rendered will do more of the map functionality). The control is just the means in which it is rendered on the page to make it easy to add to any of our dozens of website by anyone by simply adding the control and filling out a few parameters of the control and wallah it displays.

What is different about my control is that based on the properties set by the user when loading the control it will connect to a webservice where it will pull the data to load onto the map out of our database, the control will then take that data and generate the Javascript necessary to render the map with it.

Generating the Javascript to do all these things is not the problem, it's getting these values into the control to load with, before it renders and from the aspx page loading the control.

In the example you posted above "count" is a property of the control itself... I will need to do this in the codebehind and i will need dozens of properties to set... This is where my confusion comes in.

Does any of that make sense?

Nugs
Avatar of Nugs

ASKER

Oh Ramuncikas, i love you man!

I got this working... SO COOL! Check it out.

Nugs


//GMapsControl.cs:
//---------------------------------------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace GMapsControl
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:GMapsControl runat=server></{0}:GMapsControl>")]
    public class GMapsControl : WebControl
    {
        public string GMapAPIKey
        {
            get
            {
                object value = this.ViewState["GMapAPIKey"];
                if (value != null)
                {
                    return value.ToString();
                }
 
                return "";
            }
            set
            {
                this.ViewState["GMapAPIKey"] = value;
            }
        }
 
        public int MapHeight
        {
            get
            {
                object value = this.ViewState["MapHeight"];
                if (value != null)
                {
                    return (int)value;
                }
 
                return 450;
            }
            set
            {
                this.ViewState["MapHeight"] = value;
            }
        }
 
        public int MapWidth
        {
            get
            {
                object value = this.ViewState["MapWidth"];
                if (value != null)
                {
                    return (int)value;
                }
                return 590;
            }
            set
            {
                this.ViewState["MapWidth"] = value;
            }
        }
 
 
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
 
            this._RegisterCommonScripts();
            this._RegisterGoogleMapsScript();
        }
 
        protected override void RenderContents(HtmlTextWriter output)
        {
            output.Write(InsertCSSStyle());
            output.Write("<div id=\"map_canvas\" style=\"width: " + this.MapWidth.ToString() + "px; height: " + this.MapHeight.ToString() + "px\"></div>");
        }
 
        private void _RegisterCommonScripts()
        {
            if (!this.Page.ClientScript.IsClientScriptBlockRegistered("GMap"))
            {
                StringBuilder script = new StringBuilder();
                script.AppendFormat("http://maps.google.com/maps?file=api&amp;v=2&amp;key={0}", this.GMapAPIKey);
                this.Page.ClientScript.RegisterClientScriptInclude(typeof(Page), "GMap", script.ToString());
            }
        }
 
        private void _RegisterGoogleMapsScript()
        {
            if (!this.Page.ClientScript.IsClientScriptBlockRegistered("GMapScript"))
            {
	//Connect to web servcie (sensitive data)
 
                this.Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "GMapScript", Javascript);
            }
        }
 
        public string InsertCSSStyle()
        {
            StringBuilder Styles = new StringBuilder();
            Styles.Append("<style type=\"text/css\">");
            Styles.Append(".InfoWindow_Links {");
            Styles.Append("font-family: Arial, Helvetica, sans-serif;");
            Styles.Append("font-size: 11px;");
            Styles.Append("font-weight: normal;");
            Styles.Append("color: #1072a5;");
            Styles.Append("}");
            Styles.Append(".InfoWindow_Links a:link");
            Styles.Append("{");
            Styles.Append("color: #1072a5;");
            Styles.Append("text-decoration: underline;");
            Styles.Append("}");
            Styles.Append(".InfoWindow_Links a:visited");
            Styles.Append("{");
            Styles.Append("color: #1072a5;");
            Styles.Append("text-decoration: underline;");
            Styles.Append("}");
            Styles.Append(".InfoWindow_Links a:active");
            Styles.Append("{");
            Styles.Append("color: #B7B7B7;");
            Styles.Append("text-decoration: none;");
            Styles.Append("font-weight: bold;");
            Styles.Append("}");
            Styles.Append(".InfoWindow_Links a:hover");
            Styles.Append("{");
            Styles.Append("color: #1072A5;");
            Styles.Append("text-decoration: none;");
            Styles.Append("}");
            Styles.Append(".InfoWindow_Text {");
            Styles.Append("font-family: Arial, Helvetica, sans-serif;");
            Styles.Append("font-size: 10px;");
            Styles.Append("color: #666666;");
            Styles.Append("padding: 4px;");
            Styles.Append("}");
            Styles.Append(".InfoWindow_Title {");
            Styles.Append("font-family: Arial, Helvetica, sans-serif;");
            Styles.Append("font-size: 12px;");
            Styles.Append("color: #333333;");
            Styles.Append("font-weight: bold;");
            Styles.Append("padding-left: 5px;");
            Styles.Append("}");
            Styles.Append(".InfoWindow_SubTitle {");
            Styles.Append("font-family: Arial, Helvetica, sans-serif;");
            Styles.Append("font-size: 11px;");
            Styles.Append("color: #666666;");
            Styles.Append("padding-left: 5px;");
            Styles.Append("}");
            Styles.Append("</style>");
 
            return Styles.ToString();
        }
 
        private void _IncludeBodyOnLoad()
        {
 
        }
    }
}
//---------------------------------------------------------------------------------------------------------------------------------------------------
 
 
 
//Default2.aspx
//---------------------------------------------------------------------------------------------------------------------------------------------------
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
 
<%@ Register Assembly="GMapsControl" Namespace="GMapsControl" TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body onload="initialize()" onunload="GUnload()">
    <form id="form1" runat="server">
        <cc1:GMapsControl ID="GoogleMapControl" runat="server" />
    </form>
</body>
</html>
//---------------------------------------------------------------------------------------------------------------------------------------------------
 
//Default2.aspx.cs
//---------------------------------------------------------------------------------------------------------------------------------------------------
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
 
public partial class Default2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        GoogleMapControl.GMapAPIKey = "askufhkjfbweufbwebcuownoefnwenfiwniofwioefnlwkenfioefniowefn";
        GoogleMapControl.MapWidth = 590;
        GoogleMapControl.MapHeight = 450;
    }
}
//---------------------------------------------------------------------------------------------------------------------------------------------------

Open in new window

Avatar of Nugs

ASKER

Is there any other advice you can give me on this before i close this up?

Nugs
Hi, Nugs.

Thanks for kind words :)

Yes, actually I have.

#1. You decided to use System.Web.Ui.WebControls.WebControl class. If  I were you I would use System.Web.UI.Control class instead. Why? Launch Lutz Roeder's Reflector and compare these two classes. (In case you don;t use it I hightly recommend it - a good software to see how things are done inside .NET Framework). Actually WebControl is an extention of Control with additional properties. Will any developer using your control use properties like BorderColor or Font? I don't think so. I even see you defining MapHeght property when there is Height property already defined in your control. Actually your control could inherit form GridView and render a map (it's just a matter of what Render() method of your control will output), but you don't need all GridView's features so no need to inherit from GridView. Same way I think about inheriting from WebControl in your case

#2. As I said WebControl class is advanced version of Control class. Again look at WebControl's Render() method. What it does it calls three other methods: RenderBeginTag, RenderContents, RenderEndTag. You're overriding RenderContents. But what about RenderBeginTag? What HTML tag it will render? I guess it's  by default. So having this will render you this HTML:
your div here
Solutions:
  - Override all there RenderBeginTag, RenderContents, RenderEndTag methods and TagKey property
  - Override Render method only
And always look at HTML your control renders (view source in browser)

#3. Avoid using output.Write() method in any RenderXXX() methods. Instead use output.AddAttribute,  output.AddStyleAttribute, output.renderBeginTag, output.renderEndTag. Whis way your code is much readable and easier to debug.

#4. Whenever you write a property for visual HTML measurements (width, height), use Unit class instead. In your MapWidth property...what if developer would like to set width to "50%"? Property of type int will not allow this. Using Unit instead of int will fix this

#5. It's a bad thing when control provides it's own style. In general controls provide functionality only and control should not care much about how it will look. It's page's developer/designer concern actually. Of cource there are exceptions like in menu-type controls where they have to have e.g. "possition: absolute" set on certain divs. But in general control should not provide it's style. Even if this is control to be used inside some company - one day you will come to interface upgrade. What will you do then: rewrite/recompile your control? What is you have a big system consisting of say 20 web applications and each using your control? Will it be easy to deploy new version or your control to each of these apps? I think css file is much easier to edit and deploy as deploying is just a matter of copying it to new location. And if you make all 20 apps to use only one css file from one general location this is even more easier.  And what if you will notice that "font-size" is too big? Recompile control project, recompile web project? No. That's not what you want. Use css file.

#6. "...output.Write("
Avatar of Nugs

ASKER

"...output.Write(" tag. Is there a way to add this to the pages body tag fromt he control?

Thanks
Nugs
Avatar of Nugs

ASKER

This is the control as it stands...

Nugs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace GMapsControl
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:GMapsControl runat=server></{0}:GMapsControl>")]
    public class GMapsControl : WebControl
    {
        private StringBuilder _MapJS = new StringBuilder();
        private StringBuilder _MapStyles = new StringBuilder();
 
        public enum MapControlType
        {
            Small,
            Large,
            None
        }
 
        //CONTROL PROPERTIES
        //------------------
        public string GMapAPIKey
        {
            get
            {
                object value = this.ViewState["GMapAPIKey"];
                if (value != null)
                {
                    return value.ToString();
                }
 
                return "";
            }
            set
            {
                this.ViewState["GMapAPIKey"] = value;
            }
        }
 
        public int MapHeight
        {
            get
            {
                object value = this.ViewState["MapHeight"];
                if (value != null)
                {
                    return (int)value;
                }
 
                return 450;
            }
            set
            {
                this.ViewState["MapHeight"] = value;
            }
        }
 
        public int MapWidth
        {
            get
            {
                object value = this.ViewState["MapWidth"];
                if (value != null)
                {
                    return (int)value;
                }
                return 590;
            }
            set
            {
                this.ViewState["MapWidth"] = value;
            }
        }
 
        public MapControlType MapControls
        {
            get
            {
                object value = this.ViewState["MapControls"];
                if (value != null)
                {
                    return (MapControlType)value;
                }
                return MapControlType.None;
            }
            set
            {
                this.ViewState["MapControls"] = value;
            }
        }
 
        public bool DisplayMapOverview
        {
            get
            {
                object value = this.ViewState["DisplayMapOverview"];
                if (value != null)
                {
                    return (bool)value;
                }
                return false;
            }
            set
            {
                this.ViewState["DisplayMapOverview"] = value;
            }
        }
 
        public bool DisplayMapTypes
        {
            get
            {
                object value = this.ViewState["DisplayMapTypes"];
                if (value != null)
                {
                    return (bool)value;
                }
                return false;
            }
            set
            {
                this.ViewState["DisplayMapTypes"] = value;
            }
        }
 
        public bool EnableScrollWheelZoom
        {
            get
            {
                object value = this.ViewState["EnableScrollWheelZoom"];
                if (value != null)
                {
                    return (bool)value;
                }
                return false;
            }
            set
            {
                this.ViewState["EnableScrollWheelZoom"] = value;
            }
        }
 
        public bool EnableLocalSearch
        {
            get
            {
                object value = this.ViewState["EnableLocalSearch"];
                if (value != null)
                {
                    return (bool)value;
                }
                return false;
            }
            set
            {
                this.ViewState["EnableLocalSearch"] = value;
            }
        }
 
        public string IconSrc
        {
            get
            {
                object value = this.ViewState["IconSrc"];
                if (value != null)
                {
                    return value.ToString();
                }
 
                return "";
            }
            set
            {
                this.ViewState["IconSrc"] = value;
            }
        }
 
        public string IconShadowSrc
        {
            get
            {
                object value = this.ViewState["IconShadowSrc"];
                if (value != null)
                {
                    return value.ToString();
                }
 
                return "";
            }
            set
            {
                this.ViewState["IconShadowSrc"] = value;
            }
        }
 
        //CONTROL RENDER METHODS
        //----------------------
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
 
            this._RegisterCommonScripts();
            this._BuildCSSStyle();
            this._BuildGoogleMapScript();
            this._RegisterGoogleMapsScript();
        }
 
        protected override void RenderContents(HtmlTextWriter output)
        {
            output.Write(_MapStyles.ToString());
            output.Write("<div id=\"map_canvas\" style=\"width: " + this.MapWidth.ToString() + "px; height: " + this.MapHeight.ToString() + "px\"></div>");
        }
 
        //CONTROL SCRIPT BUILDING AND REGISTERING
        //---------------------------------------
        private void _RegisterCommonScripts()
        {
            if (!this.Page.ClientScript.IsClientScriptBlockRegistered("GMap"))
            {
                StringBuilder script = new StringBuilder();
                script.AppendFormat("http://maps.google.com/maps?file=api&amp;v=2&amp;key={0}", this.GMapAPIKey);
                this.Page.ClientScript.RegisterClientScriptInclude(typeof(Page), "GMap", script.ToString());
            }
 
            if (EnableLocalSearch)
            {
                if (!this.Page.ClientScript.IsClientScriptBlockRegistered("GMapLocalSearch2"))
                {
                    this.Page.ClientScript.RegisterClientScriptInclude(typeof(Page), "GMapLocalSearch2", "http://www.google.com/uds/api?file=uds.js&amp;v=1.0");
                }
                if (!this.Page.ClientScript.IsClientScriptBlockRegistered("GMapLocalSearch"))
                {
                    this.Page.ClientScript.RegisterClientScriptInclude(typeof(Page), "GMapLocalSearch", "http://www.google.com/uds/solutions/localsearch/gmlocalsearch.js");
                }
            }
        }
 
        private void _RegisterGoogleMapsScript()
        {
            if (!this.Page.ClientScript.IsClientScriptBlockRegistered("GMapScript"))
            {
                this.Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "GMapScript", _MapJS.ToString());
            }
        }
 
        private void _BuildCSSStyle()
        {
           //Properties will be created for all these styles so the user can modify fonts and colors etc..
 
            _MapStyles.Append("<style type=\"text/css\">");
 
            if (EnableLocalSearch)
            {
                _MapStyles.Append("@import url(\"http://www.google.com/uds/css/gsearch.css\");");
                _MapStyles.Append("@import url(\"http://www.google.com/uds/solutions/localsearch/gmlocalsearch.css\");");
            }
 
 
            _MapStyles.Append(".InfoWindow_Links {");
            _MapStyles.Append("font-family: Arial, Helvetica, sans-serif;");
            _MapStyles.Append("font-size: 11px;");
            _MapStyles.Append("font-weight: normal;");
            _MapStyles.Append("color: #1072a5;");
            _MapStyles.Append("}");
            _MapStyles.Append(".InfoWindow_Links a:link");
            _MapStyles.Append("{");
            _MapStyles.Append("color: #1072a5;");
            _MapStyles.Append("text-decoration: underline;");
            _MapStyles.Append("}");
            _MapStyles.Append(".InfoWindow_Links a:visited");
            _MapStyles.Append("{");
            _MapStyles.Append("color: #1072a5;");
            _MapStyles.Append("text-decoration: underline;");
            _MapStyles.Append("}");
            _MapStyles.Append(".InfoWindow_Links a:active");
            _MapStyles.Append("{");
            _MapStyles.Append("color: #B7B7B7;");
            _MapStyles.Append("text-decoration: none;");
            _MapStyles.Append("font-weight: bold;");
            _MapStyles.Append("}");
            _MapStyles.Append(".InfoWindow_Links a:hover");
            _MapStyles.Append("{");
            _MapStyles.Append("color: #1072A5;");
            _MapStyles.Append("text-decoration: none;");
            _MapStyles.Append("}");
            _MapStyles.Append(".InfoWindow_Text {");
            _MapStyles.Append("font-family: Arial, Helvetica, sans-serif;");
            _MapStyles.Append("font-size: 10px;");
            _MapStyles.Append("color: #666666;");
            _MapStyles.Append("padding: 4px;");
            _MapStyles.Append("}");
            _MapStyles.Append(".InfoWindow_Title {");
            _MapStyles.Append("font-family: Arial, Helvetica, sans-serif;");
            _MapStyles.Append("font-size: 12px;");
            _MapStyles.Append("color: #333333;");
            _MapStyles.Append("font-weight: bold;");
            _MapStyles.Append("padding-left: 5px;");
            _MapStyles.Append("}");
            _MapStyles.Append(".InfoWindow_SubTitle {");
            _MapStyles.Append("font-family: Arial, Helvetica, sans-serif;");
            _MapStyles.Append("font-size: 11px;");
            _MapStyles.Append("color: #666666;");
            _MapStyles.Append("padding-left: 5px;");
            _MapStyles.Append("}");
            _MapStyles.Append("</style>");
        }
 
        private void _BuildGoogleMapScript()
        {
            _MapJS.Append("<script type=\"text/javascript\">");
            _MapJS.Append("function initialize() {");
            _MapJS.Append("if (GBrowserIsCompatible()) {");
            _MapJS.Append("var map = new GMap2(document.getElementById(\"map_canvas\"));");
            //_MapJS.Append("var mgr = new MarkerManager(map);");
            _MapJS.Append("map.setCenter(new GLatLng(0,0), 3);");
 
            _BuildMapControls();
            _BuildMarkerIcon();
 
            _MapJS.Append("function createMarker(point, windowhtml) {");
            _MapJS.Append("var marker = new GMarker(point, markerOptions);");
            _MapJS.Append("GEvent.addListener(marker, 'click', function() {");
            _MapJS.Append("marker.openInfoWindowHtml(windowhtml);");
            _MapJS.Append("}); return marker;}");
 
            _MapJS.Append("function createTabbedMarker(point,windowhtml1,windowhtml2,label1,label2) {");
            _MapJS.Append("var marker = new GMarker(point, markerOptions);");
            _MapJS.Append("GEvent.addListener(marker, \"click\", function() {");
            _MapJS.Append("marker.openInfoWindowTabsHtml([new GInfoWindowTab(label1,windowhtml1), new GInfoWindowTab(label2,windowhtml2)]);");
            _MapJS.Append("});return marker;}");
 
            _MapJS.Append("var bounds = new GLatLngBounds();");
 
            _MapJS.Append("var latlng = new GLatLng(22.890533,-109.916737);");
            _MapJS.Append("map.addOverlay(createMarker(latlng, \"" + GenerateInfoWindowHTML() + "\"));");
            _MapJS.Append("bounds.extend(latlng);");
 
            _MapJS.Append("var latlng = new GLatLng(18.127959,-66.273922);");
            _MapJS.Append("map.addOverlay(createTabbedMarker(latlng, \"" + GenerateInfoWindowHTML() + "\", \"" + GenerateInfoWindowHTML() + "\", \"Resort Info\", \"Other Info\"));");
            _MapJS.Append("bounds.extend(latlng);");
 
            _MapJS.Append("var latlng = new GLatLng(18.143921,-65.80387);");
            _MapJS.Append("map.addOverlay(createMarker(latlng, \"" + GenerateInfoWindowHTML() + "\"));");
            _MapJS.Append("bounds.extend(latlng);");
 
            _MapJS.Append("var latlng = new GLatLng(19.711576,-155.892994);");
            _MapJS.Append("map.addOverlay(createMarker(latlng, \"" + GenerateInfoWindowHTML() + "\"));");
            _MapJS.Append("bounds.extend(latlng);");
 
            _MapJS.Append("map.setZoom(map.getBoundsZoomLevel(bounds));");
            _MapJS.Append("map.setCenter(bounds.getCenter());");
            _MapJS.Append("}}</script>");
        }
 
        private void _BuildMapControls()
        {
            switch (MapControls)
            {
                case MapControlType.Small:
                    _MapJS.Append("map.addControl(new GSmallMapControl());");
                    break;
                case MapControlType.Large:
                    _MapJS.Append("map.addControl(new GLargeMapControl());");
                    break;
                case MapControlType.None:
                    break;
                default:
                    break;
            }
 
            if (DisplayMapTypes)
            {
                _MapJS.Append("map.addControl(new GMapTypeControl());");
            }
            if (DisplayMapOverview)
            {
                _MapJS.Append("map.addControl(new GOverviewMapControl());");
            }
            if (EnableScrollWheelZoom)
            {
                _MapJS.Append("map.enableScrollWheelZoom();");
            }
            if (EnableLocalSearch)
            {
                _MapJS.Append("map.addControl(new google.maps.LocalSearch(), new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(10, 20)));");
            }
        }
 
        private void _BuildMarkerIcon()
        {
            _MapJS.Append("var baseIcon = new GIcon();");
            _MapJS.Append("baseIcon.image = \"http://www.google.com/mapfiles/marker.png\";");
            _MapJS.Append("baseIcon.shadow = \"http://www.google.com/mapfiles/shadow50.png\";");
            _MapJS.Append("baseIcon.iconSize = new GSize(20, 34);");
            _MapJS.Append("baseIcon.shadowSize = new GSize(37, 34);");
            _MapJS.Append("baseIcon.iconAnchor = new GPoint(9, 34);");
            _MapJS.Append("baseIcon.infoWindowAnchor = new GPoint(9, 2);");
            _MapJS.Append("baseIcon.infoShadowAnchor = new GPoint(18, 25);");
            _MapJS.Append("markerOptions = { icon:baseIcon };");
        }
 
        //GOOLE MAP DATA BUILDING
        //-----------------------
        private string GenerateInfoWindowHTML()
        {
            StringBuilder InfoWindowHTML = new StringBuilder();
            InfoWindowHTML.Append("MT HTML");
 
            return InfoWindowHTML.ToString();
        }
    }
}

Open in new window

Hello, Nugs.

When page finishes processing (like own events, controls events, etc.) it starts to render content to be output to a webbrowser. Page cycles through control collection and calls Render() method of each member of collection.
If you open reflector and see WebControl's Render() method you would see that rendering is split into three ....errr...."stages".
protected internal override void Render(HtmlTextWriter writer)
{
    this.RenderBeginTag(writer);
    this.RenderContents(writer);
    this.RenderEndTag(writer);
}

If you override only RenderContents, then RenderBeginTag and RenderEndTag will be called.
And if you look at RenderBeginTag method of WebControl you will see that it renders the value of TagKey property.
I'll attach a sample code of how I see your control should implement rendering.

Regarding the <body onload="initialize()" onunload="GUnload()"> stuff... sorry, I'm not 100% sure but I think developer using you control will have to do this manually.

R
                // First you need a constructor of a class where you set
		// what html element your control renders
		public MySimpleControl()
			:base( HtmlTextWriterTag.Div)
		{
			
		}
 
		// next override AddAttributesToRender
		// this method adds all html attributes to your 
		// control's html element
		protected override void AddAttributesToRender(HtmlTextWriter writer)
		{
 
			
			base.AddAttributesToRender(writer);
 
			writer.AddAttribute(HtmlTextWriterAttribute.Id, "map_canvas");
			writer.AddStyleAttribute(HtmlTextWriterStyle.Width, this.MapWidth.ToString() + "px");
			writer.AddStyleAttribute(HtmlTextWriterStyle.Height, this.MapHeight.ToString() + "px");
		}
 
 
		// And now you don't need RenderContents method, because you are rendering the control
		// (html element) and it's contents will be handled by google scripts

Open in new window

Avatar of Nugs

ASKER

Ramuncikas:Thanks again i took your advice and am now using Control rather than WebControl class. It is much more clean... i Have also implemented the this.RenderBeginTag(writer); this.RenderContents(writer); this.RenderEndTag(writer); within the Render() method.

Everything is much more cleaner now... Thank you for all your help, i am sure i will have other questions on this so look out for those :)

Have a great weekend,

Nugs