ASP.NET における同期ポストバックと非同期ポストバックについて検証しています。asp:DropDownList コントロールの AutoPostBack プロパティを使用したときに行われる同期ポストバックと、さらに asp:ScriptManager と asp:UpdatePanel を使用した非同期ポストバックの動作の違いを確認しています。
スポンサーリンク
同期ポストバック ( DropDownList.AutoPostBack )
ドロップダウンリストの AutoPostBack 属性を TRUE にすることで、選択アイテムが変更されるたびに自動でポストバックが行われるようになります。そのときに呼び出されるイベントは onselectedindexchanged です。以下がサンプルコードになります。
ASPX
<form id="form1" runat="server"> <div> <!-- ドロップダウンリスト1とラベル1の定義 --> <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" onselectedindexchanged="DropDownList1_SelectedIndexChanged"> <asp:ListItem Value="1" Text="アイテム1" Selected="True"></asp:ListItem> <asp:ListItem Value="2" Text="アイテム2"></asp:ListItem> <asp:ListItem Value="3" Text="アイテム3"></asp:ListItem> </asp:DropDownList> <!-- HTML タグで定義されたコントロールに反映させる --> <input id="Text1" type="text" value="<%= DropDownList1.SelectedItem.Value + ":" + DropDownList1.SelectedItem.Text %>" /> <asp:Label ID="Label1" runat="server" Text=""></asp:Label> </div> </form>
上記のように、<%= %> で囲んだ中にコードを記述することで、HTML の input タグに選択アイテムを反映させることができます。ポストバック時に処理されるようになります。 なお、asp コントロール( runat 属性がついたもの )では、<%= %> で囲んだ中にコードを記述することはできません。
VB.NET
''' ページロードイベント Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load ' ポストバック時は何もしない If IsPostBack = True Then Return End If ' 選択されているアイテムをラベルに表示する(ドロップダウンリスト1) Label1.Text = DropDownList1.SelectedItem.Value + ":" + DropDownList1.SelectedItem.Text End Sub ''' ドロップダウンリスト1選択変更イベントハンドラー Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, _ ByVal e As EventArgs) _ Handles DropDownList1.SelectedIndexChanged ' 選択されたアイテムをラベルに表示 Label1.Text = DropDownList1.SelectedItem.Value + ":" + DropDownList1.SelectedItem.Text End Sub
C#
/// ページロードイベント protected void Page_Load(object sender, EventArgs e) { // ポストバック時は何もしない if (IsPostBack == true) { return; } // 選択されているアイテムをラベルに表示する(ドロップダウンリスト1) Label1.Text = DropDownList1.SelectedItem.Value + ":" + DropDownList1.SelectedItem.Text; } /// ドロップダウンリスト1選択変更イベントハンドラー protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) { // 選択されたアイテムをラベルに表示 Label1.Text = DropDownList1.SelectedItem.Value + ":" + DropDownList1.SelectedItem.Text; }
非同期ポストバック( asp:ScriptManager / asp:UpdatePanel )
長い前置きになりましたが、いよいよ本題の非同期ポストバックです。同期ポストバックでも十分に用件や性能を満たすこともできることは多いですが、Ajax の時代です。意味なく操作の快適性に拘る人は出てきます。
先述の ASPX に asp:ScriptManager コントロールと asp:UpdatePanel コントロールを追加するだけで画面全体を再描画することなく、画面の一部分のみの画面の更新を行うことができるようになります。
ASPX
<form id="form1" runat="server"> <!-- スクリプトマネージャー --> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <div> <!-- ドロップダウンリスト1とラベル1の定義 --> <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" onselectedindexchanged="DropDownList1_SelectedIndexChanged"> <asp:ListItem Value="1" Text="アイテム1" Selected="True"></asp:ListItem> <asp:ListItem Value="2" Text="アイテム2"></asp:ListItem> <asp:ListItem Value="3" Text="アイテム3"></asp:ListItem> </asp:DropDownList> <!-- ドロップダウンリスト1が変更された場合は、この部分のみ画面の再描画を行う --> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <input id="Text1" type="text" value="<%= DropDownList1.SelectedItem.Value + ":" + DropDownList1.SelectedItem.Text %>" /> <asp:Label ID="Label1" runat="server" Text=""></asp:Label> </ContentTemplate> <!-- 更新するタイミングを、DropDownList1コントロールのSelectedIndexChangedイベントに設定する --> <Triggers> <asp:AsyncPostBackTrigger ControlID="DropDownList1" EventName="SelectedIndexChanged" /> </Triggers> </asp:UpdatePanel> </div> </form>
UpdatePanel の ContentTemplate タグに部分的に画面の更新を行う部分を定義します。Triggers タグには、部分的に更新を行うトリガイベントを設定しています。この設定で、トリガイベントが発生すると ContentTemplate で 定義された部分のみを再描画がさせることができます。
非同期ポストバックを区別する
画面全体のポストバック(同期ポストバック)と、非同期ポストバックを区別して処理を させたい場合は、ScriptManager コントロールの IsInAsyncPostBack プロパティ ( True : 非同期ポストバック )で判断することができます。
参考