Button control subclass: click event does not fire when using UpdatePanel

Posted by nw on Stack Overflow See other posts from Stack Overflow or by nw
Published on 2010-06-03T15:50:53Z Indexed on 2010/06/03 15:54 UTC
Read the original article Hit count: 373

Filed under:
|
|
|

Using suggestions from this thread, I created a ModernButton control that uses the HTML button tag instead of input. This control works great except when embedded within an UpdatePanel control. In this case, it does trigger the partial postback, but its click event does not fire.

The control is defined thus:

[ParseChildren(false)]
[PersistChildren(true)]
public class ModernButton : Button
{
    private string _iconURL = "";

    protected override string TagName
    {
        get { return "button"; }
    }

    protected override HtmlTextWriterTag TagKey
    {
        get { return HtmlTextWriterTag.Button; }
    }

    public new string Text
    {
        get { return ViewState["NewText"] as string; }
        set { ViewState["NewText"] = HttpUtility.HtmlDecode(value); }
    }

    public string IconURL
    {
        get { return this._iconURL; }
        set { this._iconURL = value.Trim(); }
    }

    protected override void OnPreRender(System.EventArgs e)
    {
        base.OnPreRender(e);

        LiteralControl textCtrl = new LiteralControl(this.Text);
        if (this._iconURL != "")
        {
            LiteralControl openDiv = new LiteralControl(
                string.Format(
                    "<div style=\"background-image:url({0}); background-position:left center; background-repeat:no-repeat; line-height:16px; padding:3px 0 3px 22px;\">",
                    ResolveClientUrl(this._iconURL)
                )
            );
            LiteralControl closeDiv = new LiteralControl("</div>");
            Controls.AddAt(0, openDiv);
            Controls.Add(textCtrl);
            Controls.Add(closeDiv);
        }
        else
        {
            Controls.Add(textCtrl);
        }

        base.Text = UniqueID;
    }

    protected override void RenderContents(HtmlTextWriter writer)
    {
        RenderChildren(writer);
    }
}

I use it so:

<asp:UpdatePanel runat="server" ID="uxSearchPanel" ChildrenAsTriggers="true" UpdateMode="Conditional">
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="uxSearchButton" />
    </Triggers>
    <ContentTemplate>
        ...
        <ctrl:ModernButton ID="uxSearchButton" runat="server" Text="Search" IconURL="Icons/magnifier.png" OnClick="uxSearchButton_Click"></ctrl:ModernButton>
    </ContentTemplate>
</asp:UpdatePanel>

Which renders:

<div id="uxBody_uxSearchPanel">
    ...
    <button type="submit" name="ctl00$uxBody$uxSearchButton" value="ctl00$uxBody$uxSearchButton" id="uxBody_uxSearchButton">
        <div style="background-image:url(Icons/magnifier.png); background-position:left center; background-repeat:no-repeat; line-height:16px; padding:3px 0 3px 22px;">Search</div>
    </button>
</div>

The ModernButton generates a postback in every case (whether partial or full), but the server-side click event (uxSearchButton_Click) does not fire in the partial postback scenario.

© Stack Overflow or respective owner

Related posts about c#

Related posts about ASP.NET