Я пытаюсь построить UserControl;визуально настраиваемый LinkButton.Все было хорошо, пока UpdatePanels не вошли в микс: мой пользовательский контроль FancyButton вызывает обновление страницы.Для сравнения я также использую традиционный LinkButton, который работает по назначению.
//Doesn't work: Causes whole page to refresh/reload.
<as:FancyButton ID="fbUpload"
runat="server" Text="FancyButton"/>
//Works as intended: Causes ajax refresh of Update Panel.
<asp:LinkButton ID="btnUpload" runat="server" Text="LinkButton" />
Вот мой код updatePanel:
<asp:UpdatePanel ID="upNewUpdatePanel" UpdateMode="Always" ChildrenAsTriggers="true"
runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="fbUpload" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="btnUpload" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:PlaceHolder ID="detailPlaceHolder" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
А вот код для FancyButton UserControl: Я почти уверен, что проблема здесь:
using System;
using System.Web.UI.WebControls;
using System.Web.UI;
namespace Jake
{
public class FancyButton : WebControl, INamingContainer
{
private LinkButton _btn;
public string Text
{
get
{
EnsureChildControls();
return _btn.Text;
}
set
{
EnsureChildControls();
_btn.Text = value;
}
}
public string OnClientClick
{
get
{
EnsureChildControls();
return _btn.OnClientClick;
}
set
{
EnsureChildControls();
_btn.OnClientClick = value;
}
}
public delegate void ClickEventHandler(object sender, EventArgs e);
public event ClickEventHandler Click = delegate { };
protected void _btn_Click(object sender, EventArgs e)
{
Click(this, e);
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
EnsureChildControls();
}
protected override void CreateChildControls()
{
base.CreateChildControls();
_btn = new LinkButton { ID = "btn" };
Controls.Add(_btn);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
}
protected override void Render(HtmlTextWriter writer)
{
//<a class="btn {Color} btn-{Color}{CssClass?}{hasImage?}">
writer.AddAttribute(HtmlTextWriterAttribute.Class, "fancyButton");
_btn.RenderBeginTag(writer);
if (Text != null)
{
writer.Write(Text);
}
_btn.RenderEndTag(writer);
}
}
}
TL; DR: обычная кнопка связи работает как асинхронный триггер;мой кастом, кнопки UserControl нет.Что я делаю не так?
Решение из принятого ответа
Унаследовав LinkButton
вместо WebControl
, обновление панели Async работаеткак предполагалось.Кроме того, все эти надоедливые override
методы стали ненужными.
namespace Jake
{
public class FancyButton : LinkButton
{
public string Color
{
get
{
if ( ViewState["Color"] != null && ((string)ViewState["Color"]).Length > 0)
{
return ((string)ViewState["Color"]).ToLower();
}
else return "white";
}
set { ViewState["Color"] = value; }
}
public string Icon
{
get { return (string)ViewState["Icon"]; }
set { ViewState["Icon"] = value; }
}
protected override void Render(HtmlTextWriter writer)
{
//<a class="btn {Color} btn-{Color}{CssClass?}{hasImage?}">
writer.AddAttribute(HtmlTextWriterAttribute.Class, string.Format("fancyButton {0}{1}{2}",
this.Color,
CssClass.Length > 0 ? " " + CssClass : string.Empty,
Icon != null && Icon.Length > 0 ? " hasIcon" : String.Empty));
this.RenderBeginTag(writer);
// <span>
writer.RenderBeginTag(HtmlTextWriterTag.Span);
// <div class="icon {IconClass}"></div>
if (Icon != null)
{
writer.AddAttribute(HtmlTextWriterAttribute.Class, string.Format("icon {0}{1}",
Icon,
Text != null ? " btnIconPadding" : ""));
writer.RenderBeginTag(HtmlTextWriterTag.Div);
writer.RenderEndTag();
}
if (Text != null)
{
writer.Write(Text);
}
// </span>
writer.RenderEndTag();
this.RenderEndTag(writer);
}
}
}