问题描述
背景:我正在定制一个现有的 ASP .NET/C# 应用程序.它有自己的小框架"和开发人员在扩展/自定义其功能时遵循的约定.我目前正在扩展它的一些管理功能,框架提供了一个合同来强制执行 GetAdministrationInterface()
方法,该方法返回 System.Web.UI.Control
.在托管 GUI 界面的页面的 Page_Load()
方法期间调用此方法.
Background: I am customizing an existing ASP .NET / C# application. It has it's own little "framework" and conventions for developers to follow when extending/customizing its functionality. I am currently extending some of it's administrative functionality, to which the framework provides a contract to enforce implementation of the GetAdministrationInterface()
method, which returns System.Web.UI.Control
. This method is called during the Page_Load()
method of the page hosting the GUI interface.
问题:我的 GUI 中有三个按钮,每个按钮都分配了一个事件处理程序.我的管理 GUI 加载得非常好,但是单击任何按钮都不会像我期望的那样做.但是,当我再次单击它们时,这些按钮会起作用.
Problem: I have three buttons in my GUI, each of which have been assigned an Event Handler. My administration GUI loads up perfectly fine, but clicking any of the buttons doesn't do what I expect them to do. However, when I click them a second time, the buttons work.
我在每个事件处理程序方法的开头放置了断点并单步执行我的代码.在第一次单击时,没有触发任何事件处理程序.在第二次点击时,他们开火了.
I placed breakpoints at the beginning of each event handler method and stepped through my code. On the first click, none of the event handlers were triggered. On the second click, they fired.
有什么想法吗?
按钮定义示例(在 GetAdministrationInterface
内)
Example of Button Definition (within 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
Page_Load
Method that calls GetAdministrationInterface
protected void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsAsync)
{
List<AdministrationInterface> interfaces = <DATABASE CALL>;
foreach(AdministrationInteface ai in interfaces)
{
placeholderDiv.Controls.Add(ai.GetAdministrationInterface());
}
}
}
推荐答案
好伤心!我知道这会是一件愚蠢的事情.当然,这完全是我的错,而且我对 ASP .NET 缺乏了解.
Good grief! I knew it was going to be something this stupid. Purely my fault of course and my lack of knowledge in ASP .NET.
在进行了大量 Google 搜索并最终因怀疑是运行自动化脚本的机器人而被 Google 屏蔽后,我设法挤入最后一次搜索并偶然发现了这个 文章.已经到了放弃的地步,我尽我最大的努力阅读这篇文章,没有一次跳过 10 行,也没有寻找漂亮的图片.在标题为为动态创建的控件分配 ID 的部分中,我读到了这些神奇而最快乐的词:
After doing a multitude of Google searches and eventually being blocked by Google on suspicion of being a bot running automated scripts, I managed to squeeze in one last search in and stumbled across this article. Already at the point of giving up, I tried my best to read the article without skipping 10 lines at a time or looking for pretty pictures. In the section titled Assigning IDs to Dynamically Created Controls, I read these magical and most joyful words:
如果您在单击不起作用的按钮之前和单击它之后查看源 HTML,您会注意到一个小的差异.这些按钮在回发之前和之后具有不同的 HTML ID.我在 post-back 之前得到了 ctl04 和 ctl05,在 post-back 之后得到了 ctl02 和 ctl03.
If you view the source HTML before you click the not-working button and after you have clicked it, you will notice a small difference. The buttons have different HTML IDs before and after the post-back. I got ctl04 and ctl05 before the post-back and ctl02 and ctl03 after the post-back.
ASP.NET 按钮通过在 Request.Form 集合中检查其 ID 的值来识别事件.(实际上,情况不同,控件不会自行检查 Request.Form 集合.页面通过其 ID 将发布数据传递给控件,并将其传递给已注册以接收有关发布数据的通知的控件).ASP.NET 不会触发 Click 事件,因为按钮的 ID 在回发之间发生了变化.您单击的按钮和之后看到的按钮是 ASP.NET 的不同按钮.
ASP.NET button recognizes events by checking for a value for its ID in the Request.Form collection. (In truth it happens differently and controls do not check Request.Form collection by themselves. Page passes post data to controls by their IDs and to controls that are registered to be notified about post data). ASP.NET does not fire the Click event, because the button's ID has changed between the post-backs. The button you have clicked and the button you see after are different buttons for ASP.NET.
果然,当我第一次查看 HTML 时,我的按钮的 ID 为 ctl04$ctl36
.单击按钮后,我的按钮的 ID 为 ctl04$ctl33
.
Sure enough, when I viewed the HTML the first time, my button had the ID ctl04$ctl36
. After clicking the button, my button had the ID ctl04$ctl33
.
所以你有它!我所要做的就是在按钮上设置 ID,然后就可以了!现在正在调用我的事件处理程序!
So there you have it! All I had to do was set the ID on the buttons and presto! My event handlers are now being called!
示例解决方案:
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...
}
花两天时间真是太棒了……
What a great way to spend two days...
这篇关于ASP .NET Button 事件处理程序不会在第一次单击时触发,而是在 PostBack 后的第二次单击时触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!