简体   繁体   English

页面加载后重新创建页面时动态创建的按钮,但不会触发

[英]Dynamically created button after page load realoads the page but does not fire the

I have a problem with asp.net event system. 我对asp.net事件系统有疑问。

As the page is being loaded for the first time, a DropDownList is being populated and that's it. 当页面第一次被加载时,一个DropDownList就被填充了。 On the list SelectedIndexChange the page does a page postback and loads some more info, dynamically creating buttons for it based on some data taken out from the DB. 在列表SelectedIndexChange上,页面进行页面回发并加载更多信息,并根据从数据库中提取的一些数据为其动态创建按钮。

And at this point all works as expected, the CustomDivs are created and displayed correctly. 至此,所有工作均按预期进行,CustomDivs已创建并正确显示。 The problems happens when i click on one of the dynamically created buttons, the page does the postback, goes trouhg the page load but never enters the method of the button that was clicked. 当我单击动态创建的按钮之一时,就会发生问题,该页面会执行回发操作,会麻烦页面加载,但永远不会输入所单击按钮的方法。

Looking around in the internet i read something about event handlers must be created in the Page_Load method to registered. 环顾互联网,我读到一些有关事件处理程序的信息,必须在Page_Load方法中创建该事件处理程序才能注册。 So i even modified the code behind so that the CaricaPostazioni() method would be fired in the Page_Load, but that did not work. 因此,我什至修改了后面的代码,以使CaricaPostazioni()方法在Page_Load中被触发,但这没有用。 I also tried some other stuff like AutoPostBack property or UseSubmitBheaviour or CausesValidation but nothing seems to work as expected. 我还尝试了其他一些东西,例如AutoPostBack属性或UseSubmitBheaviour或CausesValidation,但似乎没有任何效果。

I should say that this page is a content page of master page that does absolutely nothing in it's Page_Load() 我应该说此页面是母版页的内容页面,在它的Page_Load()中绝对不执行任何操作

Any one can help me in this matter? 在这件事上有人可以帮助我吗? Thank you very much! 非常感谢你!

Here is the code behind of assegnapostazione.aspx 这是assegnapostazione.aspx背后的代码



    using Industry4_camerana_gruppo1.App_Code;
    using Industry4_camerana_gruppo1.App_Code.Dao;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    namespace Industry4_camerana_gruppo1 {

        public partial class assegnapostazione : System.Web.UI.Page {

            static List Macchinisti = null;

            protected void Page_Load(object sender, EventArgs e) {

                if (Macchinisti == null) {
                    Macchinisti = new daoUtente().GetByRuolo("macchinista");

                    drp_Macchinisti.Items.Add(new ListItem("Seleziona...", "-1"));
                    foreach (Utente U in Macchinisti) {
                        drp_Macchinisti.Items.Add(new ListItem(U.Username, U.ID.ToString()));
                    }

                }

            }

            public void CaricaPostazioni() {

                //if (drp_Macchinisti.SelectedValue == "-1") return;

                int IDUtente = Convert.ToInt32(drp_Macchinisti.SelectedItem.Value);

                List Postazioni = new daoPostazioni().GetAll();
                Dictionary Relazioni = new daoPostazioni().GetUtentePostazioni(IDUtente);

                if (Postazioni != null) {
                    Panel row = new Panel();
                    row.CssClass = "row";
                    int i = 0;
                    foreach (Postazione p in Postazioni) {
                        if (i % 4 == 0) {
                            pnl_Postazioni.Controls.Add(row);
                            row = new Panel();
                            row.CssClass = "row";
                        }
                        if (Relazioni.ContainsKey(p.ID)) {
                            row.Controls.Add(CustomDiv(p, IDUtente, true));
                        } else {
                            row.Controls.Add(CustomDiv(p, IDUtente, false));
                        }
                        i++;
                    }
                    pnl_Postazioni.Controls.Add(row);
                }

            }

            public Panel CustomDiv(Postazione P, int IDUtente, bool Assegnato) {

                //  
                //        
                //            
                //            
                //                Foratura
                //            
                //        
                //    

                Panel wrapper = new Panel();
                wrapper.CssClass = "col";

                Panel card = new Panel();
                card.CssClass = "card text-center postazione form-group";

                Image img = new Image();
                img.CssClass = "mx-auto d-block width-70";
                img.ID = "btn_" + P.ID;
                img.ImageUrl = "~/imgs/ic" + P.Tipo + ".png";

                Panel cardTitle = new Panel();
                cardTitle.CssClass = "card-title";

                Label title = new Label();
                title.Text = P.Tipo.ToUpper() + " - " + P.Tag;

                Button btn = new Button();
                //btn.ID = "btn_" + P.ID + IDUtente;
                btn.Attributes.Add("PID", P.ID.ToString());
                btn.Attributes.Add("UID", IDUtente.ToString());
                //btn.UseSubmitBehavior = true;
                if (Assegnato) {
                    btn.Click += new EventHandler(btn_Rimuovi_Click);
                    //btn.Click += delegate {
                    //    btn_Rimuovi_Click(btn, null);
                    //};
                    btn.CssClass = "btn btn-warning mx-auto form-control";
                    btn.Text = "Rimuovi";
                } else {
                    btn.Click += new EventHandler(btn_Assegna_Click);
                    //btn.Click += delegate {
                    //    btn_Assegna_Click(btn, null);
                    //};
                    btn.CssClass = "btn btn-success mx-auto form-control";
                    btn.Text = "Assegna";
                }

                card.Controls.Add(img);
                cardTitle.Controls.Add(title);
                card.Controls.Add(cardTitle);
                card.Controls.Add(btn);
                wrapper.Controls.Add(card);

                return wrapper;

            }

            protected void drp_Macchinisti_SelectedIndexChanged(object sender, EventArgs e) {
                CaricaPostazioni();
            }

            protected void btn_Rimuovi_Click(object sender, EventArgs e) {
                Button btn = (Button)sender;
                new daoPostazioni().AddRelazione(Convert.ToInt32(btn.Attributes["UID"]), Convert.ToInt32(btn.Attributes["PID"]));
            }

            protected void btn_Assegna_Click(object sender, EventArgs e) {
                Button btn = (Button)sender;
                new daoPostazioni().DeleteRelazione(Convert.ToInt32(btn.Attributes["UID"]), Convert.ToInt32(btn.Attributes["PID"]));
            }

        }

    }

Well, I have an answer for you but I don't think you are going to like it. 好吧,我有一个答案给您,但我认为您不会喜欢它。

Due to the stateless nature of webforms, any controls that you add dynamically to a form on a postback will also need to be added back to the page and have it's server events rebound during the OnInit event. 由于Web窗体的无状态性质,因此,在回发时动态添加到窗体的任何控件也都需要重新添加到页面,并使它的服务器事件在OnInit事件期间反弹。

I've created a minimal example that can demonstrate what's going on with this behavior so you can better understand what's happened. 我创建了一个最小的示例,可以演示此行为的发生情况,以便您可以更好地了解发生了什么。

ButtonTest.aspx ButtonTest.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ButtonTest.aspx.cs" Inherits="ButtonTest.ButtonTest" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form runat="server">
        <asp:Panel runat="server" ID="ButtonPanel">
            <asp:Button runat="server" ID="ButtonAdd" OnClick="ButtonAddClick" Text="Click Me"></asp:Button>
        </asp:Panel>
    </form>
</body>
</html>

And the code behind: 以及后面的代码:

ButtonTest.aspx.cs ButtonTest.aspx.cs

using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;

namespace ButtonTest
{
    public partial class ButtonTest : System.Web.UI.Page
    {
        static List<Button> buttons = new List<Button>();
        static bool allowItToWork = true;
        protected override void OnInit(EventArgs e)
        {
            if(Page.IsPostBack && allowItToWork)
            {
                foreach (var button in buttons)
                {
                    button.Click += ButtonAddClick; // Comment me out and added button's will do nothing when clicked.
                    ButtonPanel.Controls.Add(button);
                }
            }
        }

        protected void ButtonAddClick(object sender, EventArgs e)
        {
            var button = new Button();
            button.Click += ButtonAddClick;
            button.Text = "Click Me Too";
            buttons.Add(button);
            ButtonPanel.Controls.Add(button);
        }
    }
}

You can toggle between desirable and undesirable behavior by changing the value of the allowItToWork boolean. 您可以通过更改allowItToWork布尔值来在所需行为与不良行为之间进行切换。

When it's set to true, the OnInit overload is adding all buttons back onto the page, as well as applying their event handlers again, because those handlers seem to be lost during the PostBack (unsure on why this happens.) You can click away and new buttons will be added onto the form forever and ever. 设置为true时,OnInit重载会将所有按钮添加回页面上,并再次应用其事件处理程序,因为这些处理程序似乎在PostBack期间丢失了(不确定为什么会发生这种情况。)新按钮将永久添加到表单上。

When it's set to false, the added button will appear whenever you click the initial button, but it won't fire an event handler as it's no longer bound, and clicking the original button repeatably won't continue to add additional buttons, you'll only ever see a single one, and that one will disappear on PostBack if clicked. 如果将其设置为false,则每当您单击初始按钮时,就会出现添加的按钮,但是由于不再绑定事件处理程序,因此它不会触发事件处理程序,并且反复单击原始按钮将不会继续添加其他按钮,只会看到一个,如果单击它,它将在PostBack上消失。

So, the end result of this is essentially that you're stuck reconstructing the whole shebang in the OnInit event. 因此,这的最终结果实质上是您在OnInit事件中无法重新构建整个shebang。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 asp.net 中继器按钮不会在第一页加载时触发事件,但在回发后会触发 - asp.net Repeater Button does not fire event on first page load but after postback it does 在Page_Load()中动态创建的控件 - Dynamically created controls in Page_Load() 通过页面加载时动态创建的按钮单击事件更新列表项。 (索引超出范围) - Updating list items through dynamically created button click event on page load. (Index was out of range) 如何防止按钮单击时页面加载事件触发 - How to prevent page load event fire on button click 回发后如何在页面加载中触发datalist_ItemCommand? - How to fire datalist_ItemCommand in page load after postback? C# 为什么 OnItemDataBound 在 Page_Load 之前触发? - C# Why does OnItemDataBound fire before Page_Load? 在Page_Load上获取动态创建的文本框的ID和值 - Getting IDs and values of dynamically created text boxes on Page_Load 如何在动态创建的gridview中触发按钮事件 - How to fire the button event in gridview created dynamically 为什么我动态创建的用户控件不触发按钮单击事件 - Why does my dynamically created user control doesn't fire button click event asp:button以编程方式创建:EventHandler不触发 - asp:button Created Programmatically: EventHandler does not fire
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM