I have created a custom server control. It looks great and the rendered HTML is also as it should be. I initially had it extending the ControlContainer and now it extends the WebControl (both behave the same.) It has two properties, ImageUrl and Text. Essentially it will render a generic HTML tag with an and tags within it.
My problem is that the ServerClick event that is exposed (by NamingContainer I beleive) doesn't seem to fire. If I add any of the ASP buttons (Link, Image or regular) and associate to that Click event it fires but of course I have extra rendered content. It successfully runs the javascript and does the __dopostback call. But it must not see the given control ID or something because the event never gets fired.
using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
namespace PLSO.Info.Web.UI {
[DefaultEvent("Submit")]
[DefaultProperty("Text")]
[ToolboxData("<{0}:ComboButton runat=\"server\"> </{0}:ComboButton>")]
public class ComboButton : WebControl {
    private HtmlImage imageControl;
    private HtmlGenericControl spanControl;
    private static readonly object EventSubmitKey = new object();
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("")]
    [Description("The text to display on the button.")]
    public string Text {
        get { return ViewState["NewText"] as string; }
        set { ViewState["NewText"] = value; }
    }
    [DefaultValue("")]
    [Bindable(true)]
    [Category("Appearance")]
    [UrlProperty()]
    [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
    public string ImageUrl {
        get {
            EnsureChildControls();
            return this.imageControl.Src;
        }
        set {
            EnsureChildControls();
            this.imageControl.Src = value;
        }
    } // ImageUrl - Property
    public override string CssClass {
        get { return ViewState["CssClass"] as string; }
        set { ViewState["CssClass"] = value; }
    }
    [Category("Action")]
    [Description("Raised when the user clicks the button.")]
    public event EventHandler Submit {
        add { Events.AddHandler(EventSubmitKey, value); }
        remove { Events.RemoveHandler(EventSubmitKey, value); }
    }
    protected virtual void OnSubmit(EventArgs e) {
        EventHandler SubmitHandler = (EventHandler)Events[EventSubmitKey];
        if (SubmitHandler != null)
            SubmitHandler(this, e);
    }
    void ComboButton_Submit(object sender, EventArgs e) {
        OnSubmit(EventArgs.Empty);
    }
    protected override void CreateChildControls() {
        Controls.Clear();
        imageControl = new HtmlImage();
        imageControl.Src = this.ImageUrl;
        imageControl.Alt = this.Text;
        this.Controls.Add(imageControl);
        spanControl = new HtmlGenericControl("span");
        spanControl.InnerText = this.Text;
        this.Controls.Add(spanControl);
        this.Submit += new EventHandler(ComboButton_Submit);
        ChildControlsCreated = true;
    }
    protected override void Render(HtmlTextWriter writer) {
        PostBackOptions pbo = new PostBackOptions(this);
        AddAttributesToRender(writer);
        writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
        writer.AddAttribute("onclick", string.Format("javascript:{0}", Page.ClientScript.GetPostBackEventReference(pbo)));
        writer.RenderBeginTag(HtmlTextWriterTag.Button);
        imageControl.RenderControl(writer);
        spanControl.RenderControl(writer);
        writer.RenderEndTag();
    }
    }
}
Here is my markup. I put in this control and then a regular ASP:Button. That regular button's event gets hit! Not mine.
<ucs:ComboButton ID="btnT4" runat="server" Text="Please" CssClass="PButtonCombo" ImageUrl="~/Styles/icons/edit-find.png" OnSubmit="btnT4_Submit" />
<asp:Button ID="btnT5" runat="server" Text="TEST" onclick="btnT5_Click" UseSubmitBehavior="False" />
And here is the rendered HTML:
<button id="MainContent_btnT4" class="PButtonCombo" onclick="javascript:__doPostBack('ctl00$MainContent$btnT4','')"><img src="../Styles/icons/edit-find.png" alt="Please" /><span>Please</span></button>
<input type="button" name="ctl00$MainContent$btnT5" value="TEST" onclick="javascript:__doPostBack('ctl00$MainContent$btnT5','')" id="MainContent_btnT5" />
I have to believe I am close but just missing something. Been tweaking it for hours today, PLEASE HELP!
EDIT:
Thanks to @James answer, all I did was add the following to the top of the above example. It did the trick but now fires twice. Not sure why? So that is my current question:
public class ComboButton : WebControl, IPostBackEventHandler {
    public void RaisePostBackEvent(string eventArgument) {
        OnClick(new EventArgs());
    }
    [Category("Action")]
    [Description("Raised when the user clicks the button.")]
    public event EventHandler Click;
    protected virtual void OnClick(EventArgs e) {
        if (Click != null)
            Click(this, e);
    }
EDIT 2 == SOLUTION
using System.ComponentModel;
using System.Drawing.Design;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
namespace PLSO.Info.Web.UI {
[DefaultEvent("Submit")]
[DefaultProperty("Text")]
[ToolboxData("<{0}:ComboButton runat=\"server\"> </{0}:ComboButton>")]
public class ComboButton : Button {
    private HtmlImage imageControl;
    private HtmlGenericControl spanControl;
    [DefaultValue("")]
    [Bindable(true)]
    [Category("Appearance")]
    [UrlProperty()]
    [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
    public string ImageUrl {
        get {
            EnsureChildControls();
            return this.imageControl.Src;
        }
        set {
            EnsureChildControls();
            this.imageControl.Src = value;
        }
    } // ImageUrl - Property
    protected override void CreateChildControls() {
        Controls.Clear();
        imageControl = new HtmlImage();
        imageControl.Src = this.ImageUrl;
        imageControl.Alt = this.Text;
        this.Controls.Add(imageControl);
        spanControl = new HtmlGenericControl("span");
        spanControl.InnerText = this.Text;
        this.Controls.Add(spanControl);
        ChildControlsCreated = true;
    } // CreateChildControls - Method - Override
    protected override void Render(HtmlTextWriter writer) {
        PostBackOptions pbo = new PostBackOptions(this);
        AddAttributesToRender(writer);
        writer.RenderBeginTag(HtmlTextWriterTag.Button);
        imageControl.RenderControl(writer);
        spanControl.RenderControl(writer);
        writer.RenderEndTag();
    } // Render - Event - Override
  }
}
				
                        
Try implementing the
IPostBackEventHandlerinterface:Here's an article that explains the implementation of the
IPostBackEventHandlerinterface:http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackeventhandler.aspx
EDIT
If your events are in some way dependent on data, you need to implement the
IPostBackDataHandlerinterface. For example, you would use theIPostBackDataHandlerinterface to fire theOnTextChangedevent of a TextBox:Here's an article that explains the implementation of the
IPostBackDataHandlerinterface:http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackdatahandler.aspx