动态添加的DropDownlists不会触发SelectedIndexChanged事件

pil*_*ust 3 c# asp.net

我看到很多关于这个主题的事情,但我无法找到解决方案.我添加了许多下拉列表与一个事件,但他们没有触发SelectedIndexChanged evet.这是drplist创建者代码:

foreach (var row in cmdSelectCats.ExecuteReader())
{
    var id = row["ProductCategoryID"].ToString();

    var dropDownStatus = new DropDownList {ID = "DrpStatus-" + id};

    dropDownStatus.Items.Add(new ListItem("Aktif", "1"));
    dropDownStatus.Items.Add(new ListItem("Pasif", "2"));

    dropDownStatus.AutoPostBack = true; 
    dropDownStatus.SelectedIndexChanged += Status_SelectedIndexChanged;

    var tableCell = new TableCell();
    tableCell.Controls.Add(dropDownStatus);
    dropDownStatus.SelectedValue = row["ProductCategoryStatusID"].ToString();
    tableRow.Cells.Add(tableCell);
    TblCatList.Rows.Add(tableRow);
}
Run Code Online (Sandbox Code Playgroud)

当然是我的活动:

public void Status_SelectedIndexChanged(object sender, EventArgs e)
{
    //DO SOMETHING
} 
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Jup*_*aol 17

这是一个常见问题,它与页面生命周期有关:

看看以下问题:

单击按钮阵列上的事件

单击事件后按钮阵列消失

动态创建ImageButton

现在,在创建动态控件时要记住的基本步骤是:

  • PreInit当您不使用母版页时,应该创建动态控件,如果是,则在Init事件中创建控件
  • 避免在这些事件中设置可以在每个帖子中更改的属性,因为在应用视图状态时(在事件后),属性将被覆盖
  • 每次发布页面时都必须创建动态控件,避免这种情况if(!this.IsPostBack) this.CreatemyDynamicControls();
  • 当你在PreInitInit事件中创建控件时,它们的状态将自动设置在一个post事件中,这意味着LoadComplete如果你的控件将包含它们的状态,即使你在每个帖子中再次创建它们,甚至你没有明确设置它们他们的州.注意当您处理在设计时创建的控件时,此行为是不同的,在这种情况下,已设置状态的事件是Load事件
  • 事件订阅应该在PageLoadComplete它们之前发生,否则它们不会被引发

请考虑MSDN中的以下描述

如果控件是在运行时动态创建的,或者在数据绑定控件的模板中以声明方式创建,则它们的事件最初不会与页面上其他控件的事件同步.例如,对于在运行时添加的控件,Init和Load事件可能在页面生命周期的后期发生,而不是以声明方式创建的控件的相同事件.因此,从实例化它们开始,模板中动态添加的控件和控件会一个接一个地引发它们的事件,直到它们赶上将其添加到Controls集合中的事件.

以上对我来说并不是那么清楚,但我发现了以下内容.以下TextBox是在设计时创建的

    protected void Page_PreInit(object sender, EventArgs e)
    {
        this.txtDesignTextBox1.Text = "From PreInit";
        this.txtDesignTextBox1.Text += DateTime.Now.ToString();
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        this.txtDesignTextBox2.Text = "From Init";
        this.txtDesignTextBox2.Text += DateTime.Now.ToString();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        this.txtDesignTextBox3.Text = "From Load";
        this.txtDesignTextBox3.Text += DateTime.Now.ToString();
    }
Run Code Online (Sandbox Code Playgroud)

乍一看,您可能会认为在每个帖子中所有文本框都使用当前日期更新,但事实并非如此,因为它们是在设计时创建的,它们严格遵循ASP.Net页面生命周期,这意味着,它们的状态在PreInit和Init事件之后被覆盖,只有txtDesignTextBox3在每个帖子中更新,因为在设置了视图状态后(在事件中)Text更新它的属性Load.

但是对于动态控件,行为是不同的,请记住MSDN描述:

对于在运行时添加的控件,Init和Load事件可能会在页面生命周期的后期发生

考虑以下:

    protected void Page_PreInit(object sender, EventArgs e)
    {
        var textBox = new TextBox { Text = "From PreInit", Width = new Unit("100%") };
        textBox.Text += DateTime.Now.ToString();
        this.myPlaceHolder.Controls.Add(textBox);
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        var textBox = new TextBox { Text = "From Init", Width = new Unit("100%") };
        textBox.Text += DateTime.Now.ToString();
        this.myPlaceHolder.Controls.Add(textBox);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        var textBox = new TextBox { Text = "From Load", Width = new Unit("100%") };
        textBox.Text += DateTime.Now.ToString();
        this.myPlaceHolder.Controls.Add(textBox);
    }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,控件的行为略有不同,在这种情况下,在每个帖子中,控件永远不会更新,甚至不会更新Load事件中创建的控件

原因是它们的生命周期事件发生在页面生命周期的后期,这意味着即使在Load事件之后它们的状态也会被覆盖

要解决此问题,您可以使用该LoadComplete事件,在这种情况下您可以更改动态控件的状态:

    protected void Page_LoadComplete(object sender, EventArgs e)
    {
        var textBox = new TextBox { Text = "From LoadComplete", Width = new Unit("100%") };
        textBox.Text += DateTime.Now.ToString();
        this.myPlaceHolder.Controls.Add(textBox);
    }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,状态将在每个帖子中更新.

但是,请考虑您应该在事件之前订阅动态控件事件,LoadComplete否则它们将不会被引发.

......我知道我讨厌这种行为,这就是我喜欢MVC的原因

至于在设计时创建的控件的快速参考:注意如何LoadViewState方法被调用PreInitInit事件,但在之前Load的事件.该Load事件被认为是稳定的,因为在这种情况下您可以访问控件的视图状态.还要注意,RaisePostBackEvent方法表示引起该后背面的控制事件,这可以是,所述SelectedIndexChanged,Click等该事件被处理之后Load事件

在此输入图像描述

有关完整的详细规范,请阅读MSDN页面生命周期文档