背景:我正在定制现有的ASP .NET/C#应用程序.它有自己的小"框架"和开发人员在扩展/定制其功能时遵循的约定.我目前正在扩展它的一些管理功能,框架提供了一个合同来强制执行GetAdministrationInterface()
返回的方法System.Web.UI.Control
.在Page_Load()
托管GUI界面的页面的方法期间调用此方法.
问题:我的GUI中有三个按钮,每个按钮都分配了一个事件处理程序.我的管理GUI加载完全正常,但单击任何按钮不会做我期望他们做的事情.但是,当我第二次单击它们时,按钮会起作用.
我在每个事件处理程序方法的开头放置了断点并逐步执行了我的代码.在第一次单击时,没有触发任何事件处理程序.在第二次点击时,他们开除了.
有任何想法吗?
按钮定义示例(内GetAdministrationInterface
)
public override Control GetAdministrationInterface() { // more code... Button btn = new Button(); btn.Text = "Click Me!"; btn.Click += new EventHandler(Btn_Click); // more code... }
事件处理程序方法定义的示例
void Btn_Click(object sender, EventArgs e) { // Do Something }
Page_Load
调用的方法 GetAdministrationInterface
protected void Page_Load(object sender, System.EventArgs e) { if (!Page.IsAsync) { Listinterfaces = ; foreach(AdministrationInteface ai in interfaces) { placeholderDiv.Controls.Add(ai.GetAdministrationInterface()); } } }
John.. 66
好悲伤!我知道这将是一个愚蠢的事情.纯粹是我的错,当然我在ASP .NET中缺乏知识.
在进行了大量谷歌搜索并最终被谷歌封锁,因为他怀疑自己是一个运行自动脚本的机器人,我设法挤进了最后一次搜索并偶然发现了这篇文章.在放弃的时候,我尽力阅读这篇文章,一次不跳过10行或者寻找漂亮的照片.在标题为动态创建控件的分配ID的部分中,我阅读了这些神奇且最快乐的词:
如果您在单击"不工作"按钮之前查看源HTML,并且在单击它之后,您会发现一个小的差异.这些按钮在回发之前和之后具有不同的HTML ID.我在回发前得到了ctl04和ctl05,在回发后得到了ctl02和ctl03.
ASP.NET按钮通过在Request.Form集合中检查其ID的值来识别事件.(事实上,它的发生方式不同,控件不会自行检查Request.Form集合.Page通过它们的ID将传递数据传递给控件,并将注册的控件传递给控制后发布数据的控件).ASP.NET不会触发Click事件,因为按钮的ID在回发之间已经更改.您单击的按钮和您看到的按钮是ASP.NET的不同按钮.
果然,当我第一次看HTML时,我的按钮有了ID ctl04$ctl36
.单击按钮后,我的按钮具有ID ctl04$ctl33
.
所以你有它!我所要做的就是在按钮上设置ID并预先设置!我的事件处理程序现在正在调用!
样品解决方案
public override Control GetAdministrationInterface() { // more code... Button btn = new Button(); btn.Text = "Click Me!"; // !!THE BANE OF MY EXISTENCE!! btn.ID = "The_Bane_of_My_Existence"; // !!THE BANE OF MY EXISTENCE!! btn.Click += new EventHandler(Btn_Click); // more code... }
多么好的方式花两天时间......
好悲伤!我知道这将是一个愚蠢的事情.纯粹是我的错,当然我在ASP .NET中缺乏知识.
在进行了大量谷歌搜索并最终被谷歌封锁,因为他怀疑自己是一个运行自动脚本的机器人,我设法挤进了最后一次搜索并偶然发现了这篇文章.在放弃的时候,我尽力阅读这篇文章,一次不跳过10行或者寻找漂亮的照片.在标题为动态创建控件的分配ID的部分中,我阅读了这些神奇且最快乐的词:
如果您在单击"不工作"按钮之前查看源HTML,并且在单击它之后,您会发现一个小的差异.这些按钮在回发之前和之后具有不同的HTML ID.我在回发前得到了ctl04和ctl05,在回发后得到了ctl02和ctl03.
ASP.NET按钮通过在Request.Form集合中检查其ID的值来识别事件.(事实上,它的发生方式不同,控件不会自行检查Request.Form集合.Page通过它们的ID将传递数据传递给控件,并将注册的控件传递给控制后发布数据的控件).ASP.NET不会触发Click事件,因为按钮的ID在回发之间已经更改.您单击的按钮和您看到的按钮是ASP.NET的不同按钮.
果然,当我第一次看HTML时,我的按钮有了ID ctl04$ctl36
.单击按钮后,我的按钮具有ID ctl04$ctl33
.
所以你有它!我所要做的就是在按钮上设置ID并预先设置!我的事件处理程序现在正在调用!
样品解决方案
public override Control GetAdministrationInterface() { // more code... Button btn = new Button(); btn.Text = "Click Me!"; // !!THE BANE OF MY EXISTENCE!! btn.ID = "The_Bane_of_My_Existence"; // !!THE BANE OF MY EXISTENCE!! btn.Click += new EventHandler(Btn_Click); // more code... }
多么好的方式花两天时间......
我有同样的问题,但这里接受的答案并没有引起它.我有一个文本框和一个搜索按钮,第一次点击按钮没有执行搜索.该按钮的事件处理程序未被命中.但是第二次单击该按钮确实在服务器上触发了该事件.原因如下:
如果您将
其AutoPostBack
设置为true
,则在键入文本框然后移动以单击按钮后,文本框会在失去焦点时立即进行回发.因此,按钮的单击甚至不计算(由于文本框的事件,页面已经回发).这就是为什么当您再次单击该按钮时,它的工作原理是因为文本框不涉及第二个回发.
设置to 的AutoPostBack
属性以解决此问题.false
快速解决方法是为您在页面上加载的ASCX控件设置ID.例如,如果您的代码是这样的:
UserControl SpecsControl = (UserControl)Page.LoadControl("../name.ascx"); SpecsContainer.Controls.Add(SpecsControl);
那么你需要添加一行(在Controls.Add之前):
SpecsControl.ID = "Aribtrary_Name";
然后在第一次单击时触发您的处理程序方法.