ASP .NET按钮事件处理程序不会在第一次单击时触发,而是在PostBack后的第二次单击时触发

时间:2010-05-04 13:46:29

标签: c# asp.net event-handling

后台:我正在自定义现有的ASP .NET / C#应用程序。它有自己的小“框架”和开发人员在扩展/定制其功能时遵循的约定。我目前正在扩展其中的一些管理功能,框架提供了一个合同来强制执行GetAdministrationInterface()方法,该方法返回System.Web.UI.Control。在托管GUI界面的页面的Page_Load()方法期间调用此方法。

问题:我的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)
    {
        List<AdministrationInterface> interfaces = <DATABASE CALL>;
        foreach(AdministrationInteface ai in interfaces)
        {
            placeholderDiv.Controls.Add(ai.GetAdministrationInterface());
        }
    }
}

8 个答案:

答案 0 :(得分:65)

好悲伤!我知道这将是一个愚蠢的事情。纯粹是我的错,当然我在ASP .NET中缺乏知识。

在进行了大量的Google搜索并最终被谷歌封锁,因为他怀疑自己是一个运行自动脚本的机器人,我设法挤进了最后一次搜索并偶然发现了article。在放弃的时候,我尽力阅读这篇文章,一次不跳过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...
}

花两天时间的好方法......

答案 1 :(得分:18)

我有同样的问题,但这里接受的答案并没有引起它。我有一个文本框和一个搜索按钮,第一次点击按钮没有执行搜索。该按钮的事件处理程序未被命中。但是第二次单击该按钮确实在服务器上触发了该事件。原因如下:

如果<asp:Textbox>的{​​{1}}设置为AutoPostBack,则在输入文本框然后移动到单击按钮后,文本框会立即返回它失去焦点的那一刻。因此,按钮的单击甚至不计算(由于文本框的事件,页面已经回发)。这就是为什么当您再次单击该按钮时,它会起作用,因为第二个回发中不涉及文本框。

true的{​​{1}}属性设置为AutoPostBack以解决此问题。

答案 2 :(得分:5)

快速解决方法是为您在页面上加载的ASCX控件设置ID。例如,如果您的代码是这样的:

        UserControl SpecsControl = (UserControl)Page.LoadControl("../name.ascx");
        SpecsContainer.Controls.Add(SpecsControl);

然后你需要添加一行(在Controls.Add之前):

            SpecsControl.ID = "Aribtrary_Name";

然后在第一次点击时触发你的处理程序方法。

答案 3 :(得分:1)

我遇到了同样的问题。我的第一次点击后我的按钮冻结了。对我来说,当我禁用按钮的EnableViewState属性时,这个恼人的问题就解决了。

答案 4 :(得分:1)

对我而言,UpdatePanel,我的Button和我的TextBox都在UpdatePanel内,所以当我回发时,它会引起一些奇怪的行为。它把它带到了UpdatePanel之外并修复了它。

答案 5 :(得分:0)

虽然很难确切地知道没有看到完整的Page_load方法,但它确实闻起来有点像事件处理程序在页面重新加载之前没有挂钩。

例如:

if (IsPostBack) {
    // Add handlers here ...
}

答案 6 :(得分:0)

我有同样的问题。我在互联网上搜索我没有找到解决方案。之后,我找到了示例代码并使用了它。它对我有用。网站链接如下:

http://www.c-sharpcorner.com/UploadFile/abhikumarvatsa/calling-an-Asp-Net-C-Sharp-method-web-method-using-javascript/

答案 7 :(得分:0)

即使我有同样的问题。原因是“localhost:1656 / secure / login.aspx? ReturnUrl =%2f ”。 如果请求包含%2f 作为查询字符串,即使“%2f ”表示“ / ”,第一篇文章也不会成功。

通过在pageload中进行条件检查来避免这种情况的一种方法

protected void Page_Load(object sender, EventArgs e)
{
    string queryString = Request.QueryString.ToString();
    if(queryString == "ReturnUrl=%2f")
    {
        Response.Redirect("/secure/login.aspx");
    }
}