1

私は現在、c# と asp.net を使用して Web サイトに取り組んでいます。この目的のために、動的コントロールを作成する必要がありますが、いくつか問題があります。私はすでに公式ドキュメントを読み、多くのチュートリアルを検索しましたが、残念ながら、誰もこの問題を修正することを許可してくれませんでした.

これは、私がやろうとしていることの非常に単純化された例です。

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

試してみます:

    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

ページが最初にロードされたときにコントロールを作成していますが、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 に答える