#contents *Microsoft ASP.NET AJAXを使う2 [#x8be42c5] [[前回>../80]]はUpdatePanelコントロールの基本的な使い方について説明しましたが、今回は一つのページにUpdatePanelを複数配置するケースに絞ってより詳しく説明します。 **複数のUpdatePanelがある時に特定のUpdatePanelだけが更新されるようにする [#updatemode] まずは、一つのページにUpdatePanelを複数配置した時にどのようになるか確認してみましょう。そのために、UpdatePanelを2つ配置し、それぞれのUpdatePanelの中にButtonとLabelコントロールを配置したページを作成します。具体的なコードは、以下のようにします。 #code(vbnet){{ <%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Label1.Text = DateTime.Now.ToString() Label2.Text = DateTime.Now.ToString() End Sub Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) Label1.Text = DateTime.Now.ToString() Label2.Text = DateTime.Now.ToString() End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title>UpdatePanelテスト</title> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Button ID="Button1" runat="server" Text="更新1" OnClick="Button1_Click" /> <asp:Label ID="Label1" runat="server"></asp:Label> </ContentTemplate> </asp:UpdatePanel> <asp:UpdatePanel ID="UpdatePanel2" runat="server"> <ContentTemplate> <asp:Button ID="Button2" runat="server" Text="更新2" OnClick="Button2_Click" /> <asp:Label ID="Label2" runat="server"></asp:Label> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html> }} #code(csharp){{ <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button1_Click(object sender, EventArgs e) { Label1.Text = DateTime.Now.ToString(); Label2.Text = DateTime.Now.ToString(); } protected void Button2_Click(object sender, EventArgs e) { Label1.Text = DateTime.Now.ToString(); Label2.Text = DateTime.Now.ToString(); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title>UpdatePanelテスト</title> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Button ID="Button1" runat="server" Text="更新1" OnClick="Button1_Click" /> <asp:Label ID="Label1" runat="server"></asp:Label> </ContentTemplate> </asp:UpdatePanel> <asp:UpdatePanel ID="UpdatePanel2" runat="server"> <ContentTemplate> <asp:Button ID="Button2" runat="server" Text="更新2" OnClick="Button2_Click" /> <asp:Label ID="Label2" runat="server"></asp:Label> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html> }} このサンプルでは、Button1をクリックしても、Button2をクリックしても、UpdatePanel1とUpdatePanel2の両方が更新されます。このように一つのページに複数のUpdatePanelと複数のトリガーを配置した時、デフォルトでは、どのトリガーを使っても全てのUpdatePanelが更新されます。これは、デフォルトではUpdatePanelのUpdateModeプロパティがAlwaysだからです。 しかし、あるトリガーでは、あるUpdatePanelしか更新しない(例えば上記の例では、Button1をクリックした時はUpdatePanel2は更新せずに、UpdatePanel1しか更新しないなど)というのが決まっているのであれば、上記の例のようにすべてのUpdatePanelが更新されてしまうというのは、無駄が多すぎます。更新しないUpdatePanelの情報(HTML)もサーバーが送信しているのです。 関連付けられたトリガーだけがそのUpdatePanelを更新できるようにするには、UpdateModeプロパティをConditionalにします。例えば、上記のサンプルでButton1をクリックした時だけUpdatePanel1が更新されるようにするには、UpdatePanel1のUpdateModeプロパティをConditionalに変更します。 実際に上記のサンプルのUpdatePanel1のUpdateModeプロパティをConditionalに変更してみてください。このようにすると、Button1をクリックした時はUpdatePanel1とUpdatePanel2の両方が更新されますが、Button2をクリックした時はUpdatePanel1だけが更新されます。つまり、UpdatePanel1はUpdateModeプロパティをConditionalにしたため、Button2ボタンでは更新されず、Button1ボタンでのみ更新できます。UpdatePanel2はUpdateModeプロパティがAlwaysのため、Button1ボタンとButton2ボタンのどちらでも更新されてしまいます。 複数のUpdatePanelをページに配置した時は、UpdatePanelのUpdateModeプロパティをConditionalにするというのが基本となるでしょう。 **プログラムでUpdatePanelを更新する [#g8083d8c] プログラムでUpdatePanelを更新するには、UpdatePanelのUpdateメソッドを呼び出します。例えば、先ほどの最後の例のようにUpdatePanel1のUpdateModeプロパティをConditionalにしたときに、Button2をクリックしてUpdatePanel2も更新されるようにするには、Button2のClickイベントハンドラでUpdatePanel1のUpdateメソッドを呼び出します。 #code(vbnet){{ Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) Label1.Text = DateTime.Now.ToString() Label2.Text = DateTime.Now.ToString() 'UpdatePanel1を更新する UpdatePanel1.Update() End Sub }} #code(csharp){{ protected void Button2_Click(object sender, EventArgs e) { Label1.Text = DateTime.Now.ToString(); Label2.Text = DateTime.Now.ToString(); //UpdatePanel1を更新する UpdatePanel1.Update(); } }} **UpdatePanel内のコントローラによってそのUpdatePanelが更新されるのを防ぐ [#sdb69e20] 今で紹介してきた例では、UpdatePanel内にあるコントロールによって、自分自身のUpdatePanelは否応なしに更新されていました。しかし、UpdatePanelのChildrenAsTriggersプロパティをFalseにすることにより、そのUpdatePanelの中にあるコントロールによってそのUpdatePanelが更新されなくなります。 ChildrenAsTriggersプロパティをFalseにするならば、UpdateModeプロパティは必ずConditionalにしなければなりません。UpdateModeプロパティがAlwaysの時にChildrenAsTriggersプロパティをFalseにすると例外がスローされます。 ChildrenAsTriggersプロパティの動作について、具体例を見てみましょう。[[前の前の例>#updatemode]]で、UpdatePanel1のUpdateModeプロパティをConditionalに、ChildrenAsTriggersプロパティをFalseにしてみてください。すると、Button1をクリックしてもUpdatePanel1は更新されなくなり、UpdatePanel2だけが更新されるようになります。 [[ドキュメントによると>http://asp.net/ajax/documentation/live/mref/P_System_Web_UI_UpdatePanel_ChildrenAsTriggers.aspx]]ChildrenAsTriggersプロパティを使用するのは、2つ以上のUpdatePanelがあり、あるUpdatePanelから他のUpdatePanelを更新させたいが、自分自身は更新させたくないようなケースであるということです。 **入れ子になったUpdatePanel [#t17e3cec] ChildrenAsTriggersプロパティがTrueならば、そのUpdatePanelの中にあるコントロールによってUpdatePanelが更新されると説明しましたが、入れ子のUpdatePanelの場合はちょっと違います。入れ子の親のUpdatePanelのUpdateModeプロパティがConditionalならば、子のUpdatePanel内にあるコントロールによって親のUpdatePanelは更新されません。 例えば以下のような例では、子のUpdatePanel2内にあるButton2をクリックしても、親のUpdatePanel1は更新されません。 #code(vbnet){{ <%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Label1.Text = DateTime.Now.ToString() Label2.Text = DateTime.Now.ToString() End Sub Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) Label1.Text = DateTime.Now.ToString() Label2.Text = DateTime.Now.ToString() End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <!-- 親UpdatePanel --> <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="親更新" /> <asp:Label ID="Label1" runat="server"></asp:Label> <br /> <!-- 子UpdatePanel --> <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:Button ID="Button2" runat="server" Text="子更新" OnClick="Button2_Click" /> <asp:Label ID="Label2" runat="server"></asp:Label> </ContentTemplate> </asp:UpdatePanel> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html> }} #code(csharp){{ <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button1_Click(object sender, EventArgs e) { Label1.Text = DateTime.Now.ToString(); Label2.Text = DateTime.Now.ToString(); } protected void Button2_Click(object sender, EventArgs e) { Label1.Text = DateTime.Now.ToString(); Label2.Text = DateTime.Now.ToString(); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <!-- 親UpdatePanel --> <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="親更新" /> <asp:Label ID="Label1" runat="server"></asp:Label> <br /> <!-- 子UpdatePanel --> <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:Button ID="Button2" runat="server" Text="子更新" OnClick="Button2_Click" /> <asp:Label ID="Label2" runat="server"></asp:Label> </ContentTemplate> </asp:UpdatePanel> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html> }} 親のUpdatePanelが更新されれば、子のUpdatePanelも更新されます。上記の例では、UpdatePanel1にあるButton1をクリックすれば、UpdatePanel2も更新されます。 **UpdatePanelに関連付けられていないコントロールで非同期ポストバックを行う [#d0012396] UpdatePanelの中にあるコントロールやUpdatePanelのTriggersプロパティに追加されているコントロールは、通常のコントロールとは異なり、非同期ポストバックのトリガーとなり、Ajax機能を実現させています。このようなコントロールはScriptManagerによって非同期ポストバックコントロールとして登録されます。 これらの方法以外でScriptManagerに非同期ポストバックコントロールを登録するには、ScriptManagerのRegisterAsyncPostBackControlメソッドを使います。通常RegisterAsyncPostBackControlメソッドはページのLoadイベントハンドラで呼び出します。 以下の例では、UpdatePanelの外にあるButton1を非同期ポストバックコントロールとして登録しています。この例では、Button1をクリックすることにより、UpdateModeがAlwaysのUpdatePanel1だけでなく、UpdateModeがConditionalのUpdatePanel2もUpdateメソッドを呼び出して更新しています。 #code(vbnet){{ <%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) 'Button1を非同期ポストバックコントロールとして登録する ScriptManager1.RegisterAsyncPostBackControl(Button1) End Sub Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Label1.Text = DateTime.Now.ToString() Label2.Text = DateTime.Now.ToString() 'UpdatePanel2を更新する UpdatePanel2.Update() End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <asp:Button ID="Button1" runat="server" Text="更新" OnClick="Button1_Click" /> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server"></asp:Label> </ContentTemplate> </asp:UpdatePanel> <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:Label ID="Label2" runat="server"></asp:Label> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html> }} #code(csharp){{ <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { //Button1を非同期ポストバックコントロールとして登録する ScriptManager1.RegisterAsyncPostBackControl(Button1); } protected void Button1_Click(object sender, EventArgs e) { Label1.Text = DateTime.Now.ToString(); Label2.Text = DateTime.Now.ToString(); //UpdatePanel2を更新する UpdatePanel2.Update(); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <asp:Button ID="Button1" runat="server" Text="更新" OnClick="Button1_Click" /> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server"></asp:Label> </ContentTemplate> </asp:UpdatePanel> <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:Label ID="Label2" runat="server"></asp:Label> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html> }} //これより下は編集しないでください #pageinfo(,2007-12-21 (金) 03:59:45,DOBON!,2007-12-21 (金) 04:06:39,DOBON!) |