Ali*_*Ali 9 asp.net user-controls custom-controls
我花了两天时间与另一位同事一起调查此事.我很惊讶,因为大多数解决这个问题的解决方案都有错误的解决方案,或者我认为解决方案有错误的原因.
我们有一个自定义按钮控件,需要在按下时引发ServerClick事件.以下是汇总代码:
public class MyButton : WebControl, IPostBackEventHandler
{
protected HtmlGenericControl _Button;
protected string _OnClick = "";
protected string _Name;
public event EventHandler ServerClick;
// etc...
public MyButton()
{
Width = Unit.Pixel(100);
_Button = new HtmlGenericControl("button");
Controls.Add(_Button);
}
protected override void Render(HtmlTextWriter writer)
{
_Button.Attributes.Add("id", string.IsNullOrEmpty(_Name) ? base.ID : _Name);
_Button.Attributes.Add("name", _Name);
// etc...
_OnClick = Page.ClientScript.GetPostBackEventReference(this, "");
_Button.Attributes.Add("onClick", _OnClick);
// etc...
ID = String.Empty;
Name = String.Empty;
AccessKey = String.Empty;
TabIndex = -1;
Width = Unit.Empty;
base.Render(writer);
}
protected virtual void OnServerClick()
{
if (this.ServerClick != null)
{
this.ServerClick(this, new EventArgs());
}
}
public void RaisePostBackEvent(string eventArgument)
{
this.OnServerClick();
}
}
Run Code Online (Sandbox Code Playgroud)
在浏览器端,代码使用其中两个按钮
<form>
<!-- etc ... -->
<div class="row actionBar">
<PGSC:MyButton Name="btnAccept" ID="btnAccept" LabelID="3244" TabIndex="70" runat="server" OnServerClick="AcceptClickHandler"/>
<PGSC:MyButton Name="btnClose" ID="btnClose" LabelID="349" OnClick="window.returnValue=frmMMD.hdnMmdId.value;window.close();" TabIndex="80" runat="server" />
</div>
</form>
Run Code Online (Sandbox Code Playgroud)
问题:
接受按钮上没有引发事件.调试显示RaisePostBackEvent调用但是在关闭按钮上,没有ServerClick附加处理程序,因此没有任何反应.没有事件处理程序被调用.
笔记:
IPostBackDataHandler并呼吁RaisePostBackEvent()从IPostBackDataHandler::RaisePostDataChangedEvent()导致事件以正确的接受按钮的形式标记内时升起.RegisterRequiresRaiseEvent(btnAccept)在PageLoad期间调用正确地将事件路由到接受按钮.问题:
上面工作的解决方案是什么?还是有其他解决方案吗?我们需要它才能使页面上的多个按钮可以引发独立的点击事件,而不考虑它们在页面上的顺序或位置.
我的想法:
__doPostback()使用正确的调用__EVENTTARGET应该自动将事件正确地路由到按钮,但这实际上并没有发生.只有在我们实施的情况下才会发生IPostBackDataHandler.网络上的许多解决方案似乎都指出__doPostback,UniqueID等是实际实施时的罪魁祸首,IPostBackDataHandler似乎解决了这个问题.IPostBackEventHandler但不实现IPostBackDataHandler.我认为这是正确的,因为控件不需要引发任何数据驱动的事件.因此,实现IPostBackDataHandler它以使其工作似乎是一个黑客.RegisterRequiresRaiseEvent是不直观的,如果页面上的多个按钮想要引发事件,则无法使用.asp:Button办呢?小智 0
我模拟了一个情况。希望能帮助到你。有 MyButton WebServerControl 类:
[DefaultProperty("Text")]
[ToolboxData("<{0}:MyButton runat=server></{0}:MyButton>")]
public class MyButton : WebControl, IPostBackEventHandler
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get
{
String s = (String)ViewState["Text"];
return ((s == null) ? String.Empty : s);
}
set
{
ViewState["Text"] = value;
}
}
protected HtmlGenericControl _Button;
protected string _OnClick = "";
protected string _Name;
public event EventHandler ServerClick;
// etc...
public MyButton()
{
Width = Unit.Pixel(100);
_Button = new HtmlGenericControl("button");
Controls.Add(_Button);
}
protected override void Render(HtmlTextWriter writer)
{
_Button.Attributes.Add("id", string.IsNullOrEmpty(_Name) ? base.ID : _Name);
_Button.Attributes.Add("name", _Name);
// etc...
_OnClick = Page.ClientScript.GetPostBackEventReference(this, "");
_Button.Attributes.Add("onClick", _OnClick);
// etc...
ID = String.Empty;
//Name = String.Empty;
AccessKey = String.Empty;
TabIndex = -1;
Width = Unit.Empty;
base.Render(writer);
}
protected virtual void OnServerClick()
{
if (this.ServerClick != null)
{
this.ServerClick(this, new EventArgs());
}
}
public void RaisePostBackEvent(string eventArgument)
{
this.OnServerClick();
}
}
Run Code Online (Sandbox Code Playgroud)
然后我在一个项目中使用了我的 Web 服务器控件,假设这是 default.aspx:
<div><cc1:MyButton ID="btnAccept" runat="server" TabIndex="70" OnServerClick="AcceptClickHandler" />
<cc1:MyButton ID="btnClose" Text="Close" Width="256px" LabelID="349" runat="server" TabIndex="80" /></div><div>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</div>
Run Code Online (Sandbox Code Playgroud)
在 default.aspx.cs 中,我简单地实现了该事件:
protected void AcceptClickHandler(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToLongTimeString();
}
Run Code Online (Sandbox Code Playgroud)
AcceptClickHandler 仅在单击“接受”按钮时触发,而不是在单击“关闭”按钮时触发。
抱歉,如果我没有解决问题。
| 归档时间: |
|
| 查看次数: |
275 次 |
| 最近记录: |