これは一般的な問題であり、ページのライフサイクルに関連しています。
次の質問を見てください。
ボタンの配列のイベントをクリックします
クリックイベント後にボタン配列が消える
ImageButtonを動的に作成する
ここで、動的コントロールを作成するときに覚えておくべき基本的な手順は次のとおりです。
PreInit
マスターページを使用していない場合は、イベントで動的コントロールを作成する必要があります。マスターページを使用している場合は、Init
イベントでコントロールを作成します。
- ビューステートが適用されると(postイベントで)プロパティが上書きされるため、これらのイベントで各postで変更できるプロパティを設定することは避けてください。
- ページが投稿されるたびに動的コントロールを作成する必要があります。これは避けてください
if(!this.IsPostBack) this.CreatemyDynamicControls();
PreInit
またはイベントでコントロールを作成するとInit
、それらの状態は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();
}
一見すると、すべての投稿ですべてのテキストボックスが現在の日付で更新されていると思うかもしれませんが、設計時に作成されたため、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);
}
この場合、コントロールの動作はわずかに異なります。この場合、各投稿で、イベントで作成されたコントロールでさえも、コントロールが更新されることはありません。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);
}
この場合、状態は各投稿で更新されます。
ただし、イベントの前に動的制御イベントをサブスクライブする必要があることを考慮してください。そうしないと、LoadComplete
イベントは発生しません。
...私はこの種の行動が嫌いなことを知っているので、MVCが大好きです
設計時に作成されたコントロールのクイックリファレンスとして:およびイベントの後、イベントの前にLoadViewState
メソッドがどのように呼び出されるかに注意してください。このイベントでは、コントロールのビューステートにアクセスできるため、イベントは安定していると見なされます。また、メソッドはポストバックを引き起こした制御イベントを表していることに注意してください。これは、、、などです。このイベントはイベントの後に処理されます。PreInit
Init
Load
Load
RaisePostBackEvent
SelectedIndexChanged
Click
Load

完全な詳細仕様については、MSDNページのライフサイクルドキュメントをお読みください。