ASP.Net自定义服务器控件未触发自定义事件
我创建了自定义服务器控件。它看起来不错,呈现的HTML也是它应该的。我最初扩展了ControlContainer,现在它扩展了WebControl(两者的行为都相同)。它有两个属性,ImageUrl和Text。从本质上讲,它将呈现一个带有一个和一个标签的通用HTML标签。ASP.Net自定义服务器控件未触发自定义事件
我的问题是暴露的(通过NamingContainer我beleive)ServerClick事件似乎并没有触发。如果我添加任何ASP按钮(链接,图像或常规)并关联到该Click事件,它会触发,但当然我有额外的渲染内容。它成功运行JavaScript并执行__dopostback调用。但它不能看到给定的控件ID或某事,因为事件永远不会被解雇。
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();
}
}
}
这是我的标记。我把这个控件,然后一个常规的ASP:Button。常规按钮的事件受到打击!不是我的。
<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" />
这里是呈现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" />
我不得不相信我靠近,但只是失去了一些东西。一直在调整它几个小时今天,请帮助!
编辑:
感谢@詹姆斯的回答,我所做的只是添加以下上面的例子中的顶部。它做了伎俩,但现在发射两次。不知道为什么?所以这是我目前的问题:
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 ==解决方案
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
}
}
尝试实现IPostBackEventHandler
接口:
public class ComboButton : WebControl, IPostBackEventHandler
{
public void RaisePostBackEvent(string eventArgument)
{
OnSubmit(EventArgs.Empty);
}
}
下面是解释的执行情况的文章IPostBackEventHandler
界面:
http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackeventhandler.aspx
编辑
如果事件在某种程度上依赖于数据,您需要实现IPostBackDataHandler
接口。例如,你可以使用IPostBackDataHandler
接口触发OnTextChanged
事件的TextBox:
public class ComboButton : WebControl, IPostBackDataHandler
{
public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
return true;
}
public virtual void RaisePostDataChangedEvent()
{
}
}
下面是解释了IPostBackDataHandler
接口的实现的文章:
http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackdatahandler.aspx
你需要考虑IPostBackEventHandler
如果你不在你的控件中实现这个接口,ASP.net引擎不会将事件转发给你的控件。
+1你也应得到upvote。 –
对不起,我的意思是'IPostBackEventHandler' –
这样做(大部分) - 现在事件触发两次。看到我的答案在下面,所以我可以发布代码。 – Grandizer
您可能只需要稍微修改一下您的事件处理程序逻辑。你指的是什么答案? –