Button control subclass: click event does not fire when using UpdatePanel
- by nw
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.