1

我目前正在使用 c# 和 asp.net 开发一个网站。为此,我需要创建动态控件,但我遇到了一些问题。我已经阅读了官方文档并搜索了很多教程,但不幸的是,没有人允许我解决这个问题。

这是我正在尝试做的一个非常简化的示例;

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
        CreateControls();
    else
        UpdatePage();
}

protected void CreateControls()
{
    Button button1 = new Button();
    button1.ID = "_Button1";
    button1.Text = "Button1";
    button1.Click += new System.EventHandler(_ClickEvent);
    _Panel.Controls.Add(button1);

    Button button2 = new Button();
    button2.ID = "_Button2";
    button2.Text = "Button2";
    button2.Click += new System.EventHandler(_ClickEvent);
    _Panel.Controls.Add(button2);
}

protected void UpdatePage()
{
    Button button1 = ((Button)_Panel.FindControl("_Button1"));
    button1.Text = "I went through UpdatePage and changed";

    Button button2 = ((Button)_Panel.FindControl("_Button2"));
    button1.Text = "I went through UpdatePage and changed";
}

protected void _ClickEvent(object sender, EventArgs e)
{

}

这里的目的只是在单击其中一个按钮时更改按钮的文本。“Page_Load”方法和“UpdatePage”方法一样被正确调用,但在后者中,Button1 和 Button2 控件已经消失(它们不再在面板控件中),并且显然引发了 NullPointer 异常。

有人能解释一下吗?我知道我可能错过了有关页面生命周期的一些内容,但在任何地方都找不到任何明确的解决方案。

非常感谢 !

4

3 回答 3

0

您是在第一次加载页面时创建控件,但是 Page_Load 事件太晚了,无法将控件添加到页面并让 WebForms 知道这一点。

在初始页面加载时,在 OnInit 和 Page_Load 之间的某个位置,WebForms 会记录页面上当前有哪些控件,并将它们设置为视图状态和所有这些内容,以便他们下次发回它时知道这些控制应该在那里。如果您在 Page_Load 之前不添加控件,WebForms 就不会真正关注您添加到页面的内容,因此下次您回帖时,它们不会知道将这些控件放在页面上。

将您的 CreateControls 调用移动到 OnInit 方法中。这将告诉 WebForms 在适当的时间创建控件(大约在添加来自 .aspx 标记的任何控件的同时,尽管稍晚一些)。然后 WebForms 将知道这些控件并应用任何必要的视图状态(如果它是回发),最后在 Page_Load 上,您可以使用 UpdatePage 调用来处理控件数据。

protected override void OnInit(EventArgs e)
{
     base.OnInit(e);
     CreateControls();
}

将 OnInit 视为“将所有控件放在页面上并连接事件处理程序”。

将 Page_Load 视为“将数据放入已经存在的控件中”。

于 2015-04-16T12:25:47.833 回答
0

将尝试:

    protected String TextButton1
    {
        get { return (String) ViewState["TextButton1"]; }
        set { ViewState["TextButton1"] = value; }
    }

    protected String TextButton2
    {
        get { return (String)ViewState["TextButton2"]; }
        set { ViewState["TextButton2"] = value; }
    }

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        CreateControls();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            UpdatePage();
        }
    }

    protected void CreateControls()
    {
        Button button1 = new Button();
        button1.ID = "_Button1";
        button1.Text = String.IsNullOrEmpty(TextButton1) ? "The First Value" : TextButton1; 
        button1.Click += new System.EventHandler(_ClickEvent1);
        _Panel.Controls.Add(button1);

        Button button2 = new Button();
        button2.ID = "_Button2";
        button2.Text = String.IsNullOrEmpty(TextButton2) ? "The First Value" : TextButton2; 
        button2.Click += new System.EventHandler(_ClickEvent2);
        _Panel.Controls.Add(button2);
    }

    protected void UpdatePage()
    {
        Button button1 = ((Button)_Panel.FindControl("_Button1"));
        button1.Text = String.IsNullOrEmpty(TextButton1) ? "The First Value" : TextButton1; 

        Button button2 = ((Button)_Panel.FindControl("_Button2"));
        button2.Text = String.IsNullOrEmpty(TextButton2) ? "The First Value" : TextButton2; 
    }

    protected void _ClickEvent1(object sender, EventArgs e)
    {
        TextButton1 = "test";
        Button b = (Button) sender ;
        b.Text = TextButton1;
    }

    protected void _ClickEvent2(object sender, EventArgs e)
    {
        TextButton2 = "test";
        Button b = (Button)sender;
        b.Text = TextButton2;
    }
于 2013-09-29T20:05:34.667 回答
0

您动态创建的控件将在回发时丢失。尝试这个:

protected void Page_Load(object sender, EventArgs e)
{
        CreateControls();
        UpdatePage();
}

protected void CreateControls()
{
    Button button1 = new Button();
    button1.ID = "_Button1";
    button1.Text = "Button1";
    button1.Click += new System.EventHandler(_ClickEvent);
    _Panel.Controls.Add(button1);

    Button button2 = new Button();
    button2.ID = "_Button2";
    button2.Text = "Button2";
    button2.Click += new System.EventHandler(_ClickEvent);
    _Panel.Controls.Add(button2);
}

protected void UpdatePage()
{
    Button button1 = ((Button)_Panel.FindControl("_Button1"));
    button1.Text = "I went through UpdatePage and changed";

    Button button2 = ((Button)_Panel.FindControl("_Button2"));
    button1.Text = "I went through UpdatePage and changed";
}

protected void _ClickEvent(object sender, EventArgs e)
{

}
于 2013-09-29T17:10:00.620 回答