>我有一个 ASP.Net 页面,其中包含多个实现IPostBackEventHandler接口的控件。代码的简化版本如下:
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Custom Control
MyTextBox mytxt = new MyTextBox();
mytxt.ID = "mytxt";
mytxt.TextChange += mytxt_TextChange;
this.Form.Controls.Add(mytxt);
//Custom Control
MyButton mybtn = new MyButton();
mybtn.ID = "mybtn";
mybtn.Click += mybtn_Click;
this.Form.Controls.Add(mybtn);
}
void mybtn_Click(object sender, EventArgs e)
{
Response.Write("mybtn_Click");
}
void mytxt_TextChange(object sender, EventArgs e)
{
Response.Write("mytxt_TextChange");
}
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class MyTextBox : Control, IPostBackEventHandler
{
public event EventHandler TextChange;
protected virtual void OnTextChange(EventArgs e)
{
if (TextChange != null)
{
TextChange(this, e);
}
}
public void RaisePostBackEvent(string eventArgument)
{
OnTextChange(new EventArgs());
}
protected override void Render(HtmlTextWriter output)
{
output.Write("<input type='text' id='" + ID + "' name='" + ID + "' onchange='__doPostBack('" + ID + "','')' />");
}
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class MyButton : Control, IPostBackEventHandler
{
public event EventHandler Click;
protected virtual void OnClick(EventArgs e)
{
if (Click != null)
{
Click(this, e);
}
}
public void RaisePostBackEvent(string eventArgument)
{
OnClick(new EventArgs());
}
protected override void Render(HtmlTextWriter output)
{
output.Write("<input type='button' id='" + ID + "' name='" + ID + "' value='Click Me' onclick='__doPostBack('" + ID + "','')' />");
}
}
有 2 个自定义控件 - MyTextBox 和 MyButton 实现 IPostBackEventHandler 接口。MyTextBox 具有 TextChange 事件,MyButton 具有 Click 事件。
如果我在页面上只保留一个控件(MyTextBox 或 MyButton) - 事件将触发属性。但是,对于页面上的两个控件,即使在单击MyButton之后,MyTextBox TextChange事件也会被触发。当 MyTextBox 位于页面上时,不会触发 MyButton Click 事件。
在这里发布之前,我已经尝试了多种方法。提前感谢您的帮助。
问题的原因是您需要使用控件的 UniqueID 调用__doPostBack方法。这一点至关重要。此外,基本上服务器控件将 ClientID 呈现为元素的 ID,将 UniqueID 呈现为元素名称。因此,如果您将渲染方法更新为以下内容,则一切正常:
文本框:
output.Write("<input type='text' id='" + this.ClientID + "' name='" + this.UniqueID + "' onchange='__doPostBack('" + this.UniqueID + "','')' />");
按钮:
output.Write("<input type='button' id='" + this.ClientID + "' name='" + this.UniqueID + "' value='Click Me' onclick='__doPostBack('" + this.UniqueID + "','')' />");
编辑:
使用UniqueID似乎真的无助于解决您的问题。我不知道问题的原因,但我尝试使用基本WebControl类覆盖您的自定义文本框,这有助于解决问题。因此,您可以尝试使用此实现。
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class MyTextBox : WebControl, IPostBackEventHandler
{
public event EventHandler TextChange;
protected virtual void OnTextChange(EventArgs e)
{
if (TextChange != null)
{
TextChange(this, e);
}
}
public void RaisePostBackEvent(string eventArgument)
{
OnTextChange(new EventArgs());
}
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Input;
}
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
writer.AddAttribute(HtmlTextWriterAttribute.Onchange, Page.ClientScript.GetPostBackEventReference(this, string.Empty));
writer.AddAttribute("onkeypress", "if (WebForm_TextBoxKeyHandler(event) == false) return false;");
writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
}
}