DataGridにカラムを選択する機能を追加したサンプル

 

DataGridにカラムを選択する機能を追加したサンプル

 

このサンプルは、DataGridに表示するカラムをランタイム時に選択することができます。DataGridのカラムを選択するには、親ウィンドウからカラム選択のボタンをクリックします。カラム選択のボタンをクリックすると子ウィンドウが表示されます。

 

子ウィンドウには、2個のListBoxが表示されます。左側のListBoxには、選択可能なカラムが表示されます。右側のListBoxには、選択されたカラムが表示されます。デフォルトの状態では、得意先名が選択された状態になっています。

 

カラムを選択するには、左側のListBoxからアイテムを選択してボタンをクリックします。右側のListBoxに選択したカラムが移動します。ボタンをクリックすると、すべてのカラムが選択されます。選択されたカラムを戻すには、右側のListBoxからアイテムを選択してボタンをクリックします。すべてのカラムを戻すには、ボタンをクリックします。最後に[適用]ボタンをクリックすると、親ウィンドウのDataGridに選択したカラムが表示されます。

 

子ウィンドウから適用ボタンをクリックしても、子ウィンドウは開いた状態になっていますので、表示カラムを再選択して何回でも繰り返すことができます。子ウィンドウから、[閉じる]ボタンをクリックすると、子ウィンドウを閉じます。

 

◆プログラムDataGridSelectingColumns.aspx/PopupColumns.aspxのポイント

 

¶ポイント1 DataGridのカラムをランタイム時に追加するには

 

このサンプルでは、Page_LoadイベントでDataGridのカラムをダイナミックに追加しています。カラムを追加するには、New BoundColumn()のようにインスタンスを生成して、HeaderTextDataFieldなどのプロパティを設定してからDataGridColumnsコレクションのAdd()メソッドで追加します。DataGridには、BoundColumnButtonColumnHyperLinkColumnEditCommandColumnなどのカラムを追加することができます。TemplateColumnもダイナミックに追加することができますが、ItemTemplate専用のクラスを作成する必要があります。TemplateColumnを追加する方法については、後述するNoteを参照してください。

 

 

¶ポイント2 複数のアイテムを選択するには

子ウィンドウからカラムを選択するのに左右2個のListBoxを使用しています。複数のアイテムを選択するときは、ListBox2個作成してアイテムを移動させると使い勝手のよいユーザインタフェースになります。ListBox間でアイテムを移動するには、ListBoxItemsコレクションのAdd()RemoveAt()メソッドを使用します。すべてのアイテムを移動するときは、For Each …Nextループを使用してItemsコレクションからListItemを取得します。ListBoxのすべてのアイテムを削除するには、ItemsコレクションのClear()メソッドを使用します。

 

1個のListBoxから複数のアイテムを選択することもできますが、このサンプルのように複数のカラムを選択するときは、カラムの順番を変更できないのであまり使い勝手がよくありません。

 

 

¶ポイント3 子ウィンドウから親ウィンドウにデータを渡すには

このサンプルでは、子ウィンドウから選択したカラムを親ウィンドウに渡すのにSession変数を使用しています。子ウィンドウから親ウィンドウをポストバックさせるために、親ウィンドウのTextBoxに、選択したカラムを設定して書き換えています。

 

TextBoxが書き換えられたときに親ウィンドウをポストバックさせるには、TextBoxにクライアント側で動作するonPropertyChangeイベントを登録します。このイベントでは、Page.GetPostBackEventReference()メソッドが生成したJavaScriptを実行させてWebページをポストバックします。

 

TextBoxを経由して親ウィンドウに情報を渡すこともできますが、Session変数を使用したときは、テキストデータの他にDataSetDataTableなどのオブジェクトも渡すことができます。さらに、Session変数を使用すると複数の情報を渡すことができます。

 

◆メインプログラムDataGridSelectingColumns.aspxの解説(HTML編)

 

DataGridSelectingColumns.aspxのプレゼンテーションコンテンツの部分について解説します。行155-161ImageButtonでは、カラム選択ボタンを定義しています。このImageButtonには、OnCommandイベントが登録されています。OnCommandイベントでは、子ウィンドウを開きます。行162-168LabelTextBoxでは、件数を表示しています。

 

カラム選択ボタンと件数を表示した例

 

181-208では、DataGridを定義しています。このDataGridには、AutoGenerateColumnsプロパティにFalseを設定してカラムの自動生成機能を抑止しています。このサンプルでは、ランタイム時にDataGridのカラムを生成しますので、EnableViewStateプロパティにFalseを設定してDataGridViewStateに保存しないようにしています。EnableViewStateプロパティにFalseを設定すると、Webページロード時のオーバヘッドを軽減することができます。

 

195-207<Columns>…</Columns>では、TemplateColumnを定義しています。行196-206TemplateColumnItemTemplateでは、LinkButtonを定義しています。このLinkButtonは、レコードセレクターとして使用します。

 

DataGridLinkButtonと表示した例

 

217-222では、メッセージを表示するTextBoxを定義しています。このTextBoxReadOnlyプロパティには、Trueを設定して読み込み専用にしています。

 

227-230では、Buttonを定義しています。このButtonVisibleプロパティには、Falseを設定して非可視状態にしています。このButtonには、OnClickイベントが登録されています。OnClickイベントは、子ウィンドウから親ウィンドウをポストバックさせたときに実行されます。

 

 

リスト DataGridselectingColumns.aspxのソースコード(HTML)

136: <html>
142: <body scroll="no">
151: <form id="frmMain" runat="server">
155: <asp:ImageButton id="ibtnColumns" runat="server"
156:   CommandName="columns"
157:   OnCommand="ibtnColumns_Command"
158:   ImageUrl="../img/columns.gif"
161:   ImageAlign="Middle" />
162: <asp:Label id="lblRows" runat="server"
163:   Text="
件数" Font-Name="Tahoma" Font-Size="9pt"
164:   CssClass="rowNumber" />
165: <asp:TextBox id="txtRows" runat="server"
166:   CssClass="rowNumber"
167:   Columns="3"
168:   ReadOnly="True" />
181: <asp:DataGrid id="dgrdCustomers" runat="server"
182:   AutoGenerateColumns="False"

183:   OnItemCommand="dgrdCustomers_ItemCommand"
184:   OnItemDataBound="dgrdCustomers_ItemDataBound" :::
190:   EnableViewState="False">
195:   <Columns>
196:     <asp:TemplateColumn
197:        HeaderText="<div class='dgrdHeaderBox'>1</div>">
198:        <ItemTemplate>
199:           <asp:LinkButton id="lbtnSelect" runat="server"
200:             CommandName="Select"
201:             Text="<div class='dgrdItemArrow'>4</div>"
202:             Visible="True" />
203:        </ItemTemplate>
206:     </asp:TemplateColumn>
207:   </Columns>
208: </asp:DataGrid>
217: <asp:TextBox id="txtMessage" runat="server"
218:   Text="Display Columns"
219:   Style="background-color:SkyBlue"
220:   Columns="112"
221:   Visible="True"
222:   ReadOnly="True" />
227: <asp:Button id="btnRefresh" runat="server"
228:   Text="Hidden"
229:   Visible="False"
230:   OnClick="btnRefresh_Click" />
231: </form>
232: </body>
232: </html>

 

 

 

◆メインプログラムDataGridSelectingColumns.aspxの解説(コード編)

 

DataGridSelectingColumns.aspxは、子ウィンドウから選択したDataGridのカラムを取得してランタイム時にダイナミックに追加します。子ウィンドウから選択したカラムは、Session変数に保存して親ウィンドウに渡します。

 

Sub Page_Load()イベントの処理

 

このイベントは、DataGridSelectingColumns.aspxがロードされたときに実行されます。このイベントでは、クライアント側で動作するイベントの登録と、DataGridのカラムをダイナミックに追加して表示します。

 

10では、メッセージを表示するTextBoxにクライアント側で動作する、onPropertyChangeイベントを登録しています。onPropertyChangeイベントでは、Webページをポストバックします。GetPostBackEventReferenece()メソッドは、WebページをポストバックするJavaScriptを生成します。Webページがポストバックされると、btnRefreshイベントが実行されます。

 

11-16If…Else…End Ifでは、ページが最初にロードされたか調べています。最初にロードされたときは、Session変数にデフォルトのカラムとして得意先名(CompanyName)を保存します。ページがポストバックされたときは、Session変数に格納されているカラム情報を取得します。

 

17では、AddColumns()を呼び出してDataGridにダイナミックにカラムを追加します。AddColumns()の引数には、DataGridに追加するカラムを指定します。行18では、BindDataGrid()を呼び出してDataGridに得意先テーブルをバインドして表示します。

 

 

  9: Sub Page_Load()
 10:   txtMessage.Attributes.Add("OnPropertyChange", GetPostBackEventReference(btnRefresh))
 11:   If Not IsPostBack Then
 12:     mstrDisplayColumns = "CompanyName"
 13:     Session("DisplayColumns") = mstrDisplayColumns
 14:   Else
 15:     mstrDisplayColumns = Session("DisplayColumns")
 16:   End If
 17:   AddColumns(mstrDisplayColumns)
 18:   BindDataGrid()
 19: End Sub

 

 

Sub dgrdCustomers_ItemDataBound()イベントの処理

 

このイベントは、DataGridDataBind()メソッドが実行されたときに発生します。このイベントでは、DataGridのアイテム(DataGridItem)にクライアント側で動作するonClickイベントを登録します。これにより、DataGridの任意のセルをクリックして行を選択できるようになります

 

29: Sub dgrdCustomers_ItemDataBound(s As Object, e As DataGridItemEventArgs)
 30:   Dim lit As ListItemType = e.Item.ItemType
 31:
 32:   If lit = ListItemType.Item OrElse _
 33:     lit = ListItemType.AlternatingItem OrElse _
 34:     lit = ListItemType.SelectedItem Then
 35:     Dim lbtn As LinkButton = CType(e.Item.FindControl("lbtnSelect"), LinkButton)
 36:     e.Item.Attributes("onClick") = GetPostBackClientHyperlink(lbtn, "")
 37:     e.Item.Style("cursor") = "hand"
 38:   End If
 39: End Sub

 

 

Sub ibtnColumns_Command()イベントの処理

 

このイベントは、Webページからカラムの追加ボタンをクリックしたときに発生します。このイベントでは、InsertScriptBlock()を呼び出して、子ウィンドウを開きます。

 

45: Sub ibtnColumns_Command(s As Object, e As CommandEventArgs)
 46:   InsertScriptBlock()
 47: End Sub

 

 

Sub AddColumns()の処理

 

このサブプロシージャでは、DataGridにカラムを追加します。AddColumnsは、Page_Loadイベントから呼ばれます。

 

50では、引数に指定されたカラムを分割して配列変数に格納します。引数には、カラムがコンマ区切りで指定されています。

 

strDisplayColumns = "CustomerID, CompanyName, ContactName"

 

53-67For…Nextでは、配列変数からカラムを取り出してAddCustomerID()/AddColumn()を呼び出しています。AddCustomerID()は、DataGridに得意先IDのカラムを追加します。AddColumn()は、DataGridにその他のカラムを追加します。AddCustomerID()/AddColumn()には、引数としてBoundColumnHeaderTextDataFieldプロパティに設定する値を指定します。

 

 

49: Sub AddColumns(strDisplayColumns As String)
 50:   Dim astrColumns() As String = strDisplayColumns.Split(",")
 51:   Dim i As Integer
 52:
 53:   For i=0 To astrColumns.Length - 1
 54:     If astrColumns(i) = "CustomerID" Then
 55:       AddCustomerID("<div class='dgrdHeader'>ID</div>",astrColumns(i))
 56:     ElseIf astrColumns(i) = "CompanyName" Then
 57:       AddColumn("<div class='dgrdHeader'>
得意先名</div>",astrColumns(i))
 58:     ElseIf astrColumns(i) = "ContactName" Then
 59:       AddColumn("<div class='dgrdHeader'>
担当者名</div>",astrColumns(i))
 60:     ElseIf astrColumns(i) = "ContactTitle" Then
 61:       AddColumn("<div class='dgrdHeader'>
役職</div>",astrColumns(i))
 62:     ElseIf astrColumns(i) = "Phone" Then
 63:       AddColumn("<div class='dgrdHeader'>
電話番号</div>",astrColumns(i))
 64:     ElseIf astrColumns(i) = "Ken" Then
 65:       AddColumn("<div class='dgrdHeader'>
都道府県</div>",astrColumns(i))
 66:     End If
 67:   Next
 68: End Sub

 

 

Sub AddColumn()の処理

 

このサブプロシージャでは、DataGridにカラムを追加します。AddColumnは、AddColumns()から呼ばれます。

 

71では、BoundColumnのインスタンスを生成しています。行72-75With…End Withでは、BoundColumnHeaderTextDataFieldプロパティに値を設定しています。行76では、DataGridColumnsコレクションのAdd()メソッドでBoundColumnを追加しています。

 

70: Sub AddColumn(strHeaderText As String, strDataField As String)
 71:   Dim bc As New BoundColumn()
 72:   With bc
 73:     .HeaderText = strHeaderText
 74:     .DataField = strDataField
 75:   End With
 76:   dgrdCustomers.Columns.Add(bc)
 77: End Sub

 

 

Sub AddCustomerID()の処理

 

このサブプロシージャでは、DataGridに得意先IDのカラムを追加します。AddCustomeIDは、AddColumns()から呼ばれます。

 

80では、BoundColumnのインスタンスを生成しています。行81-85With…End Withでは、BoundColumnHeaderTextDataFieldItemStyleプロパティに値を設定しています。行86では、DataGridColumnsコレクションのAdd()メソッドでBoundColumnを追加しています。

 

79: Sub AddCustomerID(strHeaderText As String, strDataField As String)
 80:   Dim bc As New BoundColumn()
 81:   With bc
 82:     .HeaderText = strHeaderText
 83:     .DataField = strDataField
 84:     .ItemStyle.HorizontalAlign = HorizontalAlign.Right
 85:   End With
 86:   dgrdCustomers.Columns.Add(bc)
 87: End Sub

 

 

Sub BindDataGrid()の処理

 

このサブプロシージャでは、DataGridに得意先テーブルをバインドして表示します。BindDataGridは、Page_Loadイベントから呼ばれます。

 

89: Sub BindDataGrid()
 90:   Dim strSQL As String = "Select top 10 * From Customers"
 91:   Dim ds AS DataSet = CreateDataSet(strSQL)
 92:   With dgrdCustomers
 93:     .DataSource = ds.Tables(0).DefaultView()
 94:     .DataKeyField = "CustomerID"
 95:     .DataBind()
 96:     .SelectedIndex = -1
 97:   End With
 98:   txtRows.Text = ds.Tables(0).Rows.Count.ToString()
 99: End Sub

 

 

Sub InsertScriptBlock()の処理

 

このサブプロシージャでは、子ウィンドウを開くJavaScriptを生成して登録します。InsertScriptBlockは、カラムの選択ボタンをクリックしたときに、ボタンのOnCommandイベントから呼ばれます。

 

102-104では、JavaScriptwindow.open()メソッドの引数に指定するオプションを生成しています。行106-110With…End Withでは、StringBuilderAppend()メソッドで以下のJavaScriptを生成しています。

 

<script language='javascript'>
window.open('PopupColumns.aspx','_blank','features');

</script>

 

JavaScriptwindow.open()メソッドは、新規ウィンドウを開きます。Open()メソッドの引数には、urltargetfeaturesを指定します。urlには、新規ウィンドウに表示するファイルPopupColumns.aspxを指定します。

 

111では、Page.RegisterClientScriptBlock()メソッドでJavaScriptを登録します。ここで登録したJavaScriptは、Webページがロードされたときにクライアント側のブラウザから実行されます。

 

101: Sub InsertScriptBlock()
102:   Dim strFeatures As String = "height=190,width=220,left=10,top=10," & _
103:     "location=no,menubar=no,resizable=yes,scrollbars=no," & _
104:     "status=no,titlebar=yes,toolbar=no"
105:   Dim sbScript As New StringBuilder()
106:   With sbScript
107:     .Append("<script language='javascript'>" & vbCrLf)
108:     .Append(vbTab & "window.open('PopupColumns.aspx','_blank','" & strFeatures & "');" & vbCrLf)
109:     .Append("</" & "script>")
110:   End With
111:   RegisterClientScriptBlock("openWindow", sbScript.ToString)
112: End Sub

 

 

Function CreateDataSet()関数の処理

 

この関数は、データベースからレコードを抽出してDataSetを作成して返します。CreateDataSetは、BindDataGrid()から呼ばれます。CreateDataSetのの引数には、strSQLstrConnectionStringを指定します。strSQLには、データベースからレコードを抽出するSELECTステートメントを指定します。strConnectionStringには、Web.Configに登録されている<add>タグのkeyを指定します。strConnectionStringを省略したときは、デフォルトとしてconStringAccNwを使用します。

 

<add key="conStringAccNw"

  value="PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA Source=C:\WebMatrix\webdb\Nwind.mdb" />

 

123: Function CreateDataSet(strSQL As String, _
124:   Optional strConnectionString As String = "conStringAccNw") As DataSet
125:   Dim con As New OleDbConnection( _
126:     ConfigurationSettings.AppSettings(strConnectionString))
127:   Dim da As New OleDbDataAdapter(strSQL, con)
128:   Dim ds As New DataSet()
129:
130:   da.Fill(ds)
131:   Return ds
132: End Function

 

 

リスト DataGridselectingColumns.aspxのソースコード(コード編)

  1: <%@ Page language="vb" SmartNavigation="false" %>
  2: <%@ Import Namespace="System.Data" %>
  3: <%@ Import Namespace="System.Data.OleDb" %>
  4:
  5: <script language="vb" runat="server">
  6: Private mstrDisplayColumns As String
  7: Private mintBookMarkID As Integer = 0
  8:
  9: Sub Page_Load()
 19: End Sub
 20:
 21: Sub btnRefresh_Click(s As Object, e As EventArgs)
 23: End Sub
 24:
 29: Sub dgrdCustomers_ItemDataBound(s As Object, e As DataGridItemEventArgs)
 39: End Sub
 40:
 41: Sub dgrdCustomers_ItemCommand(s As Object, e As DataGridCommandEventArgs)
 43: End Sub
 44:
 45: Sub ibtnColumns_Command(s As Object, e As CommandEventArgs)
 47: End Sub
 48:
 49: Sub AddColumns(strDisplayColumns As String)
 68: End Sub
 69:
 70: Sub AddColumn(strHeaderText As String, strDataField As String)
 77: End Sub
 78:
 79: Sub AddCustomerID(strHeaderText As String, strDataField As String)
 87: End Sub
 88:
 89: Sub BindDataGrid()
 99: End Sub
100:
101: Sub InsertScriptBlock()
112: End Sub
113:
123: Function CreateDataSet(strSQL As String, _
124:   Optional strConnectionString As String = "conStringAccNw") As DataSet

132: End Function
134: </script>

 

 

◆サブプログラムPopupColumns.aspxの解説(HTML編)

 

子ウィンドウのWebフォームには、2個のListBoxとカラムを移動する4個のボタンを作成しています。左側のListBoxには、選択可能なカラムを表示します。右側のListBoxには、選択済みのカラムを表示します。ListBox間でカラムを移動するには、4種類のボタンを使用します。

 

145-150では、選択可能なカラム(候補カラム)を表示するListBoxを定義しています。このListBoxには、SelectionModeプロパティにSingleを設定していますので、複数のアイテムを選択することができません。行180-185では、選択済みのカラム(表示カラム)を表示するListBoxを定義しています。このListBoxにも、SelectionModeプロパティにSingleを設定していますので、複数のアイテムを選択することができません。

 

155-173では、4種類のButtonを定義しています。右矢印のボタンは、左側のListBoxからアイテムを選択するときに使用します。左矢印のボタンは、右側のListBoxからアイテムを戻すときに使用します。矢印が2個表示されているボタンは、ListBoxのすべてのアイテムを移動します。これらのButtonには、OnClickイベントを登録しています。OnClickイベントでは、ListBox間でアイテムを移動します。ボタンの矢印は、Webdingsフォントを使用して表示しています。Webdingsフォントでは、数字の48のように表示されます。同様に、数字の37のように表示されます。

 

 

左右に2個のListBox4個のButtonを表示した例

 

196-200では、「適用」と「閉じる」のButtonを定義しています。適用ボタンには、OnClickイベントを登録しています。OnClickイベントでは、選択済みのListBoxからカラムを取得してSession変数に保存して親ウィンドウに渡します。閉じるボタンには、クライアント側で動作するonClickイベントを登録します。クライアント側のonClickイベントでは、子ウィンドウを閉じます。

 

「適用」と「閉じる」のButtonを表示した例

 

リスト PopupColumns.aspxのソースコード(HTML)

124: <html>
130: <body>
131: <form runat="server">
142: <div style="font-family:Tahoma;font-size:8pt;">
143:   &nbsp;&nbsp;
候補カラム<br>
144: </div>
145: <asp:ListBox id="lstAvailable" runat="server"
146:   DataTextField="Container.DataItem.Text"
147:   DataValueField="Container.DataItem.Value"
148:   Rows="7"
149:   SelectionMode="Single">
150: </asp:ListBox>
155: <asp:Button id="btnAddOne" runat="server"
156:   Text="4" Style="font-family:Webdings;"
158:   OnClick="btnAddOne_Click" />
160: <asp:Button id="btnAddAll" runat="server"
161:   Text="8" Style="font-family:Webdings;"
163:   OnClick="btnAddAll_Click" />
165: <asp:Button id="btnRemoveOne" runat="server"
166:   Text="3" Style="font-family:Webdings;"
168:   OnClick="btnRemoveOne_Click" />
170: <asp:Button id="btnRemoveAll" runat="server"
171:   Text="7" Style="font-family:Webdings;"
173:   OnClick="btnRemoveAll_Click" />

177: <div style="font-family:Tahoma;font-size:8pt;">
178:   &nbsp;&nbsp;
表示カラム<br>
179: </div>
180: <asp:ListBox id="lstSelected" runat="server"
181:   DataTextField="Container.DataItem.Text"
182:   DataValueField="Container.DataItem.Value"
183:   Rows="7"
184:   SelectionMode="Single">
185: </asp:ListBox>
196: <asp:Button id="btnApply" runat="server"
197:   Text="
適用"
198:   OnClick="btnApply_Click" />
199: <asp:Button id="btnClose" runat="server"
200:   Text="
閉じる" />
206: </form>
207: </body>
207: </html>

 

 

 

◆サブプログラムPopupColumns.aspxの解説(コード編)

 

PopupColumns.aspxは、Webフォームから選択したカラムをSession変数に保存して親ウィンドウに渡します。Session変数を親ウィンドウに渡すには、子ウィンドウから親ウィンドウをポストバックさせる必要があります。

 

Sub Page_Load()イベントの処理

 

このイベントは、ページがロードされたときに発生します。このイベントでは、ページの初期化を行います。

 

9では、Session変数に保存されているカラムを取得します。行10-14If…End Ifでは、ページが最初にロードされたか調べています。ページが最初にロードされたときは、閉じるボタンにクライアント側で動作するonClickイベントを登録しています。onClickイベントでは、、JavaScriptwindow.close()メソッドを実行して子ウィンドウを閉じます。行12では、BindAvailableListBox()を呼び出してListBoxに選択可能なカラムをバインドします。行13では、BindSelectedListBox()を呼び出してListBoxに選択済みのカラムをバインドします。選択済みのカラムは、Session変数に保存されています。

 

  8: Sub Page_Load()
  9:   mstrDisplayColumns = Session("DisplayColumns")
 10:   If Not IsPostBack Then
 11:     btnClose.Attributes.Add("onclick", "window.close();")
 12:     BindAvailableListBox()
 13:     BindSelectedListBox()
 14:   End If
 15: End Sub

 

 

Sub btnAddOne_Click()イベントの処理

 

このイベントは、アイテムを選択するボタンをクリックしたときに発生します。このイベントでは、左側のListBoxから選択したアイテムを右側のListBoxに移動します。

 

18-20では、左側のListBoxからアイテムが選択されているか調べています。選択されていないときは、何もしないで戻ります。

 

21では、ListBoxから選択したアイテム(ListItem)を取得しています。行22では、右側のListBoxに、選択したアイテムを追加しています。アイテムを追加するには、ItemsコレクションのAdd()メソッドを使用します。Add()メソッドの引数には、ListItemを指定します。ListItemの引数には、Text/Valueプロパティを指定します。

 

23では、左側のListBoxから選択したアイテムを削除します。アイテムを削除するには、ItemsコレクションのRemoveAt()メソッドを使用します。RemoveAt()メソッドには、アイテムのインデックス番号を指定します。ListBoxSelectedIndexプロパティには、選択したアイテムのインデックス番号が格納されています。

 

17: Sub btnAddOne_Click(s As Object, e As EventArgs)
 18:   If lstAvailable.SelectedItem Is Nothing Then
 19:     Exit Sub
 20:   End If

 21:   Dim itm As ListItem = lstAvailable.SelectedItem
 22:   lstSelected.Items.Add(New ListItem(itm.Text, itm.Value))
 23:   lstAvailable.Items.RemoveAt(lstAvailable.selectedIndex)
 24: End Sub

 

 

Sub btnAddAll_Click()イベントの処理

 

このイベントは、すべてのアイテムを選択するボタン をクリックしたときに発生します。このイベントでは、左側のListBoxからすべてのアイテムを右側のListBoxに移動します。

 

28-30For Each…Nextでは、ListBoxItemsコレクションからListItemを取り出しています。行29では、ItemsコレクションのAdd()メッドで右側のListBoxにアイテムを追加しています。

 

31では、ItemsコレクションのClear()メソッドで左側のListBoxからすべてのアイテムを削除しています。

 

 

26: Sub btnAddAll_Click(s As Object, e As EventArgs)
 27:   Dim itm As ListItem
 28:   For Each itm In lstAvailable.Items
 29:     lstSelected.Items.Add(New ListItem(itm.Text, itm.Value))
 30:   Next
 31:   lstAvailable.Items.Clear()
 32: End Sub

 

 

Sub btnRemoveOne_Click()イベントの処理

 

このイベントは、選択したアイテムを削除するボタンをクリックしたときに発生します。このイベントでは、右側のListBoxから選択したアイテムを左側のListBoxに戻します。

 

35-37では、右側のListBoxからアイテムが選択されているか調べています。選択されていないときは、何もしないで戻ります。

 

38では、ListBoxから選択したアイテム(ListItem)を取得しています。行39では、左側のListBoxに、選択したアイテムを追加しています。アイテムを追加するには、ItemsコレクションのAdd()メソッドを使用します。

 

40では、右側のListBoxから選択したアイテムを削除します。アイテムを削除するには、ItemsコレクションのRemoveAt()メソッドを使用します。

 

34: Sub btnRemoveOne_Click(s As Object, e As EventArgs)
 35:   If lstSelected.selectedItem Is Nothing Then
 36:     Exit Sub
 37:   End If
 38:   Dim itm As ListItem = lstSelected.selectedItem
 39:   lstAvailable.Items.Add(New ListItem(itm.Text, itm.Value))
 40:   lstSelected.Items.RemoveAt(lstSelected.selectedIndex)
 41: End Sub

 

 

Sub btnRemoveAll_Click()イベントの処理

 

このイベントは、すべてのアイテムを戻すボタン をクリックしたときに発生します。このイベントでは、右側のListBoxからすべてのアイテムを左側のListBoxに戻します。

 

45-47For Each…Nextでは、ListBoxItemsコレクションからListItemを取り出しています。行46では、ItemsコレクションのAdd()メッドで左側のListBoxにアイテムを追加しています。

 

48では、ItemsコレクションのClear()メソッドで右側のListBoxからすべてのアイテムを削除しています。

 

 

43: Sub btnRemoveAll_Click(s As Object, e As EventArgs)
 44:   Dim itm As ListItem
 45:   For Each itm In lstSelected.Items
 46:     lstAvailable.Items.Add(New ListItem(itm.Text, itm.Value))
 47:   Next
 48:   lstSelected.Items.Clear()
 49: End Sub

 

 

Sub btnApply_Click()イベントの処理

 

このイベントは、Webフォームから適用ボタンをクリックしたときに発生します。このイベントでは、Webフォームから選択したカラムを取得して親ウィンドウに渡します。

 

54-63With…End Withでは、StringBuilderAppend()メソッドでListBoxから選択したカラムを追加しています。行55では、右側のListBoxからListItemCollectionを作成しています。このListItemCollectionには、選択したアイテムのListItemが格納されています。行57-62For Each…Nextでは、ListItemCollectionからListItemを取り出してValueプロパティの値をStringBuilderAppend()メソッドで追加しています。ListItemValueには、カラム名(CustomerID, CompanyName, ContactName,…)が格納されています。

 

64では、Session変数に選択したカラムを保存しています。複数のカラムを選択したときは、コンマ区切りで格納されます。

 

Session("DisplayColumns") = "CustomerID,CompanyName,ContactTitle"

 

67-72With…End Withでは、StringBuilderAppend()メソッドで以下のJavaScriptを生成しています。

 

<script language='javascript'>

window.opener.frmMain.txtMessage.value = 'Selected Columns';

</script>

 

JavaScriptwindow.opener.frmMain.txtMessage.value=では、親ウィンドウのTextBoxに選択したカラム(Selected Columns)を設定しています。TextBoxが書き換えられると、クライアント側で動作するonPropertyChangeイベントが実行されてWebページがポストバックされます。親ウィンドウがポストバックされると、Page_LoadイベントでSession変数に保存されているカラムを取得して、DataGridにカラムを追加します。

 

73では、Page.RegisterClientScriptBlock()メソッドでJavaScriptを登録しています。ここで登録したJavaScriptは、Webページがロードされたときにクライアント側のブラウザから実行されます。

 

51: Sub btnApply_Click(s As Object, e As EventArgs)
 52:   Dim sbColumns As New StringBuilder()
 53:

 54:   With sbColumns
 55:     Dim items As ListItemCollection = lstSelected.Items
 56:     Dim item As ListItem
 57:     For Each item In Items
 58:       If .Length > 0 Then
 59:         .Append(",")
 60:       End If
 61:       .Append(item.Value)
 62:     Next
 63:   End With
 64:   Session("DisplayColumns") = sbColumns.ToString()
 65:
 66:   Dim sbScript As New StringBuilder()
 67:   With sbScript
 68:     .Append("<script language='javascript'>" & vbCrLf)
 69:     .Append(vbTab & "window.opener.frmMain.txtMessage.value = '" & _
 70:       sbColumns.ToString() & "';" & vbCrLf)
 71:     .Append("</" & "script>")
 72:   End With
 73:   RegisterClientScriptBlock("columns", sbScript.ToString)
 74: End Sub

 

 

Sub BindAvailableListBox()の処理

 

このサブプロシージャでは、ListBoxに選択可能なカラムを表示します。BindAvailableListBoxは、Page_Loadイベントから呼ばれます。行78-80If…End Ifでは、得意先IDのカラムが選択されているか調べています。選択されていないときは、ListBoxItemsコレクションのAdd()メソッドで得意先IDのカラムを追加します。後続するIf…End Ifでは、得意先名、担当者名、役職部署、電話番号、都道府県のカラムが選択されていないか調べてListBoxに追加します。

 

76: Sub BindAvailableListBox()
 77:   With lstAvailable
 78:     If mstrDisplayColumns.IndexOf("CustomerID") = -1 Then
 79:       .Items.Add(New ListItem("
得意先ID","CustomerID"))
 80:     End If

 81:     If mstrDisplayColumns.IndexOf("CompanyName") = -1 Then
 82:       .Items.Add(New ListItem("
得意先名","CompanyName"))
 83:     End If
 84:     If mstrDisplayColumns.IndexOf("ContactName") = -1 Then
 85:       .Items.Add(New ListItem("
担当者名","ContactName"))
 86:     End If
 87:     If mstrDisplayColumns.IndexOf("ContactTitle") = -1 Then
 88:       .Items.Add(New ListItem("
役職部署","ContactTitle"))
 89:     End If
 90:     If mstrDisplayColumns.IndexOf("Phone") = -1 Then
 91:       .Items.Add(New ListItem("
電話番号","Phone"))
 92:     End If
 93:     If mstrDisplayColumns.IndexOf("Ken") = -1 Then
 94:       .Items.Add(New ListItem("
都道府県","Ken"))

 95:     End If
 96:   End With
 97: End Sub

 

 

Sub BindSelectedListBox()の処理

 

このプロシージャは、ListBoxに選択されているカラムを表示します。BindSelectedListBoxは、Page_Loadイベントから呼ばれます。

 

100では、すでに選択されているカラムを分割して配列変数に格納します。行104-118For…Nextでは、配列変数からカラムを取り出してListBoxに追加します。カラムをListBoxに追加するには、ItemsコレクションのAdd()メソッドを使用します。Add()メソッドの引数には、ListItemを指定します。

 

99: Sub BindSelectedListBox()
100:   Dim astrColumns() As String = mstrDisplayColumns.Split(",")
101:   Dim i As Integer
102:
103:   With lstSelected
104:     For i=0 To astrColumns.Length - 1
105:       If astrColumns(i) = "CustomerID" Then
106:         .Items.Add(New ListItem("
得意先ID","CustomerID"))
107:       ElseIf astrColumns(i) = "CompanyName" Then
108:         .Items.Add(New ListItem("
得意先名","CompanyName"))
109:       ElseIf astrColumns(i) = "ContactName" Then
110:         .Items.Add(New ListItem("
担当者名","ContactName"))
111:       ElseIf astrColumns(i) = "ContactTitle" Then
112:         .Items.Add(New ListItem("
役職部署","ContactTitle"))
113:       ElseIf astrColumns(i) = "Phone" Then
114:         .Items.Add(New ListItem("
電話番号","Phone"))

115:       ElseIf astrColumns(i) = "Ken" Then
116:         .Items.Add(New ListItem("
都道府県","Ken"))
117:       End If
118:     Next
119:   End With
120: End Sub

 

 

リスト PopupColumns.aspxのソースコード(コード編)

  1: <%@ Page language="vb" SmartNavigation="False" %>
  2: <%@ Import Namespace="System.Data" %>
  3: <%@ Import Namespace="System.Data.OleDb" %>
  4:
  5: <script language="vb" runat="server">
  6: Private mstrDisplayColumns As String
  7:
  8: Sub Page_Load()
 15: End Sub
 16:
 17: Sub btnAddOne_Click(s As Object, e As EventArgs)
 24: End Sub
 25:
 26: Sub btnAddAll_Click(s As Object, e As EventArgs)
 32: End Sub
 33:
 34: Sub btnRemoveOne_Click(s As Object, e As EventArgs)
 41: End Sub
 42:
 43: Sub btnRemoveAll_Click(s As Object, e As EventArgs)
 49: End Sub
 50:
 51: Sub btnApply_Click(s As Object, e As EventArgs)
 74: End Sub
 75:
 76: Sub BindAvailableListBox()
 97: End Sub
 98:
 99: Sub BindSelectedListBox()
120: End Sub
122: </script>

 

Note

DataGridにダイナミックに追加したカラムをPage_Loadイベントの前に復元するには

 

DataGridにダイナミックに追加したカラムはViewStateに保存されないため、Webページがポストバックされたときに復元されません。このため、Webページがポストバックされる度に、DataGridにカラムを追加する必要があります。このサンプルでは、Page_LoadイベントでWebページがポストバックされたときにダイナミックにカラムを追加してDataGridを復元しています。

 

ダイナミックに追加したカラムをPage_Loadイベントが発生する前に復元させるには、LoadViewStateをオーバライドしてDataGridにカラムを追加します。LoadViewStateは、Page_Loadイベントが発生する前に実行されますので、Page_Loadイベントから見た場合DataGridにダイナミックに追加されたカラムが常に復元されています。

 

以下のサンプルでは、Session("DisplayColumns")変数に保存されているカラムをLoadViewStateイベントでDataGridに追加しています。Page_Loadイベントが発生するときには、DataGridにカラムが追加された状態になっています。Session変数には、子ウィンドウから選択したカラムが保存されています。

 

Private Property DynamicColumnAdded() As Boolean

  Get

    If ViewState("ColumnAdded") Is Nothing Then

      Return False

    Else

      Return True

    End If

  End Get

 

  Set (ByVal Value As Boolean)

    ViewState("ColumnAdded") = Value

  End Set

End Property

 

Protected Overrides Sub LoadViewState(ByVal savedState As Object)

  MyBase.LoadViewState(savedState)

  If Me.DynamicColumnAdded Then

    Me.AddColumns(Session("DisplayColumns"))

  End If

End Sub

 

Private Sub AddColumns(strDisplayColumns As String)

  Dim astrColumns() As String = strDisplayColumns.Split(",")

  Dim i As Integer

 

  For i=0 To astrColumns.Length - 1

    If astrColumns(i) = "CustomerID" Then

      AddCustomerID("<div class='dgrdHeader'>ID</div>",astrColumns(i))

    ElseIf astrColumns(i) = "CompanyName" Then

      AddColumn("<div class='dgrdHeader'>得意先名</div>",astrColumns(i))

    ElseIf astrColumns(i) = "ContactName" Then

      AddColumn("<div class='dgrdHeader'>担当者名</div>",astrColumns(i))

    ElseIf astrColumns(i) = "ContactTitle" Then

      AddColumn("<div class='dgrdHeader'>役職</div>",astrColumns(i))

    ElseIf astrColumns(i) = "Phone" Then

      AddColumn("<div class='dgrdHeader'>電話番号</div>",astrColumns(i))

    ElseIf astrColumns(i) = "Ken" Then

      AddColumn("<div class='dgrdHeader'>都道府県</div>",astrColumns(i))

    End If

  Next

  BindDataGrid()

  Me.DynamicColumnAdded = True

End Sub

 

 

 

Note

DataGridTemplateColumnをダイナミックに追加するには

 

DataGridTemplateColumnをダイナミックに追加するには、New TemplateColumn()TemplateColumnのインスタンスを生成します。TemplateColumnHeaderTextなどのプロパティは、BoundColumnと同じように設定することができます。ItemTemplateを生成するには、ItemTemplate専用のクラスを作成する必要があります。このサンプルでは、DynamicItemTemplateのクラスを作成してLabelコントロールに得意先名(CompanyName)をバインドしています。TemplateColumnItemTemplateに、DynamicItemTemplateのインスタンスを設定したら、DataGridColumnsコレクションのAdd()メソッドでTemplateColumnを追加します。

 

Dim tc1 As New TemplateColumn()

With tc1

  .HeaderText = "<div class='dgrdHeader'>得意先名</div>"

  .ItemTemplate = New DynamicItemTemplate()

End With

dgrdCustomers.Columns.Add(tc1)

 

ItemTemplateLabelにデータをバインドするには、AddHandlerLabelにデータをバインドするイベントを登録する必要があります。BindLabelイベントでは、得意先名がNullか調べてNullのときは、LabelTextプロパティに(Null)を設定します。Nullでないときは、DataItemから得意先名を取得してLabelTextに設定します。これで、ItemTemplateに得意先名が表示されます。

 

Sub AddColumns()

  Dim tc1 As New TemplateColumn()

 

  With tc1

    .HeaderText = "<div class='dgrdHeader'>得意先名</div>"

    .ItemTemplate = New DynamicItemTemplate()

  End With

  dgrdCustomers.Columns.Add(tc1)

  BindDataGrid()

  ' DynamicColumnAdded = True

End Sub

 

Public Class DynamicItemTemplate

  Implements ITemplate

 

  Public Overridable Overloads Sub InstantiateIn(ByVal container As Control) _

    Implements ITemplate.InstantiateIn

    Dim lbl As Label = New Label()

 

    AddHandler lbl.DataBinding, AddressOf BindLabel

    container.Controls.Add(lbl)

  End Sub

 

  Public Sub BindLabel(ByVal sender As Object, ByVal e As EventArgs)

    Dim lbl As Label = CType(sender, Label)

    Dim container As DataGridItem = CType(lbl.NamingContainer, DataGridItem)

 

    If container.DataItem("CompanyName").GetType.ToString = "System.DBNull" Then

      lbl.Text = "(Null)"

    Else

      lbl.Text = container.DataItem("CompanyName")

    End If

  End Sub

End Class

 

 

ASP.NET DataGrid2のホームへ戻る