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

図 DataGridにカラムを選択する機能を追加したサンプル
このサンプルは、DataGridに表示するカラムをランタイム時に選択することができます。DataGridのカラムを選択するには、親ウィンドウからカラム選択のボタン
をクリックします。カラム選択のボタンをクリックすると子ウィンドウが表示されます。
子ウィンドウには、2個のListBoxが表示されます。左側のListBoxには、選択可能なカラムが表示されます。右側のListBoxには、選択されたカラムが表示されます。デフォルトの状態では、得意先名が選択された状態になっています。
カラムを選択するには、左側のListBoxからアイテムを選択して
ボタンをクリックします。右側のListBoxに選択したカラムが移動します。
ボタンをクリックすると、すべてのカラムが選択されます。選択されたカラムを戻すには、右側のListBoxからアイテムを選択して
ボタンをクリックします。すべてのカラムを戻すには、
ボタンをクリックします。最後に[適用]ボタンをクリックすると、親ウィンドウのDataGridに選択したカラムが表示されます。
子ウィンドウから適用ボタンをクリックしても、子ウィンドウは開いた状態になっていますので、表示カラムを再選択して何回でも繰り返すことができます。子ウィンドウから、[閉じる]ボタンをクリックすると、子ウィンドウを閉じます。
◆プログラムDataGridSelectingColumns.aspx/PopupColumns.aspxのポイント
¶ポイント1 DataGridのカラムをランタイム時に追加するには
このサンプルでは、Page_LoadイベントでDataGridのカラムをダイナミックに追加しています。カラムを追加するには、New BoundColumn()のようにインスタンスを生成して、HeaderText、DataFieldなどのプロパティを設定してからDataGridのColumnsコレクションのAdd()メソッドで追加します。DataGridには、BoundColumn、ButtonColumn、HyperLinkColumn、EditCommandColumnなどのカラムを追加することができます。TemplateColumnもダイナミックに追加することができますが、ItemTemplate専用のクラスを作成する必要があります。TemplateColumnを追加する方法については、後述するNoteを参照してください。
¶ポイント2 複数のアイテムを選択するには
子ウィンドウからカラムを選択するのに左右2個のListBoxを使用しています。複数のアイテムを選択するときは、ListBoxを2個作成してアイテムを移動させると使い勝手のよいユーザインタフェースになります。ListBox間でアイテムを移動するには、ListBoxのItemsコレクションのAdd()、RemoveAt()メソッドを使用します。すべてのアイテムを移動するときは、For Each …Nextループを使用してItemsコレクションからListItemを取得します。ListBoxのすべてのアイテムを削除するには、ItemsコレクションのClear()メソッドを使用します。
1個のListBoxから複数のアイテムを選択することもできますが、このサンプルのように複数のカラムを選択するときは、カラムの順番を変更できないのであまり使い勝手がよくありません。
¶ポイント3 子ウィンドウから親ウィンドウにデータを渡すには
このサンプルでは、子ウィンドウから選択したカラムを親ウィンドウに渡すのにSession変数を使用しています。子ウィンドウから親ウィンドウをポストバックさせるために、親ウィンドウのTextBoxに、選択したカラムを設定して書き換えています。
TextBoxが書き換えられたときに親ウィンドウをポストバックさせるには、TextBoxにクライアント側で動作するonPropertyChangeイベントを登録します。このイベントでは、Page.GetPostBackEventReference()メソッドが生成したJavaScriptを実行させてWebページをポストバックします。
TextBoxを経由して親ウィンドウに情報を渡すこともできますが、Session変数を使用したときは、テキストデータの他にDataSet、DataTableなどのオブジェクトも渡すことができます。さらに、Session変数を使用すると複数の情報を渡すことができます。
◆メインプログラムDataGridSelectingColumns.aspxの解説(HTML編)
DataGridSelectingColumns.aspxのプレゼンテーションコンテンツの部分について解説します。行155-161のImageButtonでは、カラム選択ボタンを定義しています。このImageButtonには、OnCommandイベントが登録されています。OnCommandイベントでは、子ウィンドウを開きます。行162-168のLabelとTextBoxでは、件数を表示しています。
![]()
図 カラム選択ボタンと件数を表示した例
行181-208では、DataGridを定義しています。このDataGridには、AutoGenerateColumnsプロパティにFalseを設定してカラムの自動生成機能を抑止しています。このサンプルでは、ランタイム時にDataGridのカラムを生成しますので、EnableVie
行195-207の<Columns>…</Columns>では、TemplateColumnを定義しています。行196-206のTemplateColumnのItemTemplateでは、LinkButtonを定義しています。このLinkButtonは、レコードセレクターとして使用します。
![]()
図 DataGridにLinkButtonと表示した例
行217-222では、メッセージを表示するTextBoxを定義しています。このTextBoxのReadOnlyプロパティには、Trueを設定して読み込み専用にしています。
行227-230では、Buttonを定義しています。このButtonのVisibleプロパティには、Falseを設定して非可視状態にしています。このButtonには、OnClickイベントが登録されています。OnClickイベントは、子ウィンドウから親ウィンドウをポストバックさせたときに実行されます。
リスト DataGridselectingColumns.aspxのソースコード(HTML編)
|
136:
<html> 183: OnItemCommand="dgrdCustomers_ItemCommand" |
◆メインプログラムDataGridSelectingColumns.aspxの解説(コード編)
DataGridSelectingColumns.aspxは、子ウィンドウから選択したDataGridのカラムを取得してランタイム時にダイナミックに追加します。子ウィンドウから選択したカラムは、Session変数に保存して親ウィンドウに渡します。
Sub Page_Load()イベントの処理
このイベントは、DataGridSelectingColumns.aspxがロードされたときに実行されます。このイベントでは、クライアント側で動作するイベントの登録と、DataGridのカラムをダイナミックに追加して表示します。
行10では、メッセージを表示するTextBoxにクライアント側で動作する、onPropertyChangeイベントを登録しています。onPropertyChangeイベントでは、Webページをポストバックします。GetPostBackEventReferenece()メソッドは、WebページをポストバックするJavaScriptを生成します。Webページがポストバックされると、btnRefreshイベントが実行されます。
行11-16のIf…Else…End Ifでは、ページが最初にロードされたか調べています。最初にロードされたときは、Session変数にデフォルトのカラムとして得意先名(CompanyName)を保存します。ページがポストバックされたときは、Session変数に格納されているカラム情報を取得します。
行17では、AddColumns()を呼び出してDataGridにダイナミックにカラムを追加します。AddColumns()の引数には、DataGridに追加するカラムを指定します。行18では、BindDataGrid()を呼び出してDataGridに得意先テーブルをバインドして表示します。
|
9: Sub Page_Load() |
Sub dgrdCustomers_ItemDataBound()イベントの処理
このイベントは、DataGridのDataBind()メソッドが実行されたときに発生します。このイベントでは、DataGridのアイテム(DataGridItem)にクライアント側で動作するonClickイベントを登録します。これにより、DataGridの任意のセルをクリックして行を選択できるようになります
|
29: Sub
dgrdCustomers_ItemDataBound(s As Object, e As DataGridItemEventArgs) |
Sub ibtnColumns_Command()イベントの処理
このイベントは、Webページからカラムの追加ボタンをクリックしたときに発生します。このイベントでは、InsertScriptBlock()を呼び出して、子ウィンドウを開きます。
|
45: Sub
ibtnColumns_Command(s As Object, e As CommandEventArgs) |
Sub AddColumns()の処理
このサブプロシージャでは、DataGridにカラムを追加します。AddColumnsは、Page_Loadイベントから呼ばれます。
行50では、引数に指定されたカラムを分割して配列変数に格納します。引数には、カラムがコンマ区切りで指定されています。
strDisplayColumns
= "CustomerID, CompanyName, ContactName"
行53-67のFor…Nextでは、配列変数からカラムを取り出してAddCustomerID()/AddColumn()を呼び出しています。AddCustomerID()は、DataGridに得意先IDのカラムを追加します。AddColumn()は、DataGridにその他のカラムを追加します。AddCustomerID()/AddColumn()には、引数としてBoundColumnのHeaderTextとDataFieldプロパティに設定する値を指定します。
|
49: Sub
AddColumns(strDisplayColumns As String) |
Sub AddColumn()の処理
このサブプロシージャでは、DataGridにカラムを追加します。AddColumnは、AddColumns()から呼ばれます。
行71では、BoundColumnのインスタンスを生成しています。行72-75のWith…End Withでは、BoundColumnのHeaderText、DataFieldプロパティに値を設定しています。行76では、DataGridのColumnsコレクションのAdd()メソッドでBoundColumnを追加しています。
|
70: Sub
AddColumn(strHeaderText As String, strDataField As String) |
Sub AddCustomerID()の処理
このサブプロシージャでは、DataGridに得意先IDのカラムを追加します。AddCustomeIDは、AddColumns()から呼ばれます。
行80では、BoundColumnのインスタンスを生成しています。行81-85のWith…End Withでは、BoundColumnのHeaderText、DataField、ItemStyleプロパティに値を設定しています。行86では、DataGridのColumnsコレクションのAdd()メソッドでBoundColumnを追加しています。
|
79: Sub
AddCustomerID(strHeaderText As String, strDataField As String) |
Sub BindDataGrid()の処理
このサブプロシージャでは、DataGridに得意先テーブルをバインドして表示します。BindDataGridは、Page_Loadイベントから呼ばれます。
|
89: Sub BindDataGrid() |
Sub InsertScriptBlock()の処理
このサブプロシージャでは、子ウィンドウを開くJavaScriptを生成して登録します。InsertScriptBlockは、カラムの選択ボタンをクリックしたときに、ボタンのOnCommandイベントから呼ばれます。
行102-104では、JavaScriptのwindow.open()メソッドの引数に指定するオプションを生成しています。行106-110のWith…End Withでは、StringBuilderのAppend()メソッドで以下のJavaScriptを生成しています。
<script
language='javascript'>
window.open('PopupColumns.aspx','_blank','features');
</script>
JavaScriptのwindow.open()メソッドは、新規ウィンドウを開きます。Open()メソッドの引数には、url、target、featuresを指定します。urlには、新規ウィンドウに表示するファイルPopupColumns.aspxを指定します。
行111では、Page.RegisterClientScriptBlock()メソッドでJavaScriptを登録します。ここで登録したJavaScriptは、Webページがロードされたときにクライアント側のブラウザから実行されます。
|
101:
Sub InsertScriptBlock() |
Function CreateDataSet()関数の処理
この関数は、データベースからレコードを抽出してDataSetを作成して返します。CreateDataSetは、BindDataGrid()から呼ばれます。CreateDataSetのの引数には、strSQLとstrConnectionStringを指定します。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, _ |
リスト DataGridselectingColumns.aspxのソースコード(コード編)
|
1: <%@ Page
language="vb" SmartNavigation="false" %> 132:
End Function |
◆サブプログラム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フォントでは、数字の4が
、8が
のように表示されます。同様に、数字の3が
、7が
のように表示されます。

図 左右に2個のListBoxと4個のButtonを表示した例
行196-200では、「適用」と「閉じる」のButtonを定義しています。適用ボタンには、OnClickイベントを登録しています。OnClickイベントでは、選択済みのListBoxからカラムを取得してSession変数に保存して親ウィンドウに渡します。閉じるボタンには、クライアント側で動作するonClickイベントを登録します。クライアント側のonClickイベントでは、子ウィンドウを閉じます。
![]()
図 「適用」と「閉じる」のButtonを表示した例
リスト PopupColumns.aspxのソースコード(HTML編)
|
124:
<html> 177: <div
style="font-family:Tahoma;font-size:8pt;"> |
◆サブプログラムPopupColumns.aspxの解説(コード編)
PopupColumns.aspxは、Webフォームから選択したカラムをSession変数に保存して親ウィンドウに渡します。Session変数を親ウィンドウに渡すには、子ウィンドウから親ウィンドウをポストバックさせる必要があります。
Sub Page_Load()イベントの処理
このイベントは、ページがロードされたときに発生します。このイベントでは、ページの初期化を行います。
行9では、Session変数に保存されているカラムを取得します。行10-14のIf…End Ifでは、ページが最初にロードされたか調べています。ページが最初にロードされたときは、閉じるボタンにクライアント側で動作するonClickイベントを登録しています。onClickイベントでは、、JavaScriptのwindow.close()メソッドを実行して子ウィンドウを閉じます。行12では、BindAvailableListBox()を呼び出してListBoxに選択可能なカラムをバインドします。行13では、BindSelectedListBox()を呼び出してListBoxに選択済みのカラムをバインドします。選択済みのカラムは、Session変数に保存されています。
|
8: Sub Page_Load() |
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()メソッドには、アイテムのインデックス番号を指定します。ListBoxのSelectedIndexプロパティには、選択したアイテムのインデックス番号が格納されています。
|
17: Sub btnAddOne_Click(s
As Object, e As EventArgs) 21: Dim itm As ListItem =
lstAvailable.SelectedItem |
Sub btnAddAll_Click()イベントの処理
このイベントは、すべてのアイテムを選択するボタン
をクリックしたときに発生します。このイベントでは、左側のListBoxからすべてのアイテムを右側のListBoxに移動します。
行28-30のFor Each…Nextでは、ListBoxのItemsコレクションからListItemを取り出しています。行29では、ItemsコレクションのAdd()メッドで右側のListBoxにアイテムを追加しています。
行31では、ItemsコレクションのClear()メソッドで左側のListBoxからすべてのアイテムを削除しています。
|
26: Sub btnAddAll_Click(s
As Object, e As EventArgs) |
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) |
Sub btnRemoveAll_Click()イベントの処理
このイベントは、すべてのアイテムを戻すボタン
をクリックしたときに発生します。このイベントでは、右側のListBoxからすべてのアイテムを左側のListBoxに戻します。
行45-47のFor Each…Nextでは、ListBoxのItemsコレクションからListItemを取り出しています。行46では、ItemsコレクションのAdd()メッドで左側のListBoxにアイテムを追加しています。
行48では、ItemsコレクションのClear()メソッドで右側のListBoxからすべてのアイテムを削除しています。
|
43: Sub
btnRemoveAll_Click(s As Object, e As EventArgs) |
Sub btnApply_Click()イベントの処理
このイベントは、Webフォームから適用ボタンをクリックしたときに発生します。このイベントでは、Webフォームから選択したカラムを取得して親ウィンドウに渡します。
行54-63のWith…End Withでは、StringBuilderのAppend()メソッドでListBoxから選択したカラムを追加しています。行55では、右側のListBoxからListItemCollectionを作成しています。このListItemCollectionには、選択したアイテムのListItemが格納されています。行57-62のFor Each…Nextでは、ListItemCollectionからListItemを取り出してValueプロパティの値をStringBuilderのAppend()メソッドで追加しています。ListItemのValueには、カラム名(CustomerID, CompanyName, ContactName,…)が格納されています。
行64では、Session変数に選択したカラムを保存しています。複数のカラムを選択したときは、コンマ区切りで格納されます。
Session("DisplayColumns")
= "CustomerID,CompanyName,ContactTitle"
行67-72のWith…End Withでは、StringBuilderのAppend()メソッドで以下のJavaScriptを生成しています。
<script
language='javascript'>
window.opener.frmMain.txtMessage.value
= 'Selected Columns';
</script>
JavaScriptのwindow.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) 54: With sbColumns |
Sub BindAvailableListBox()の処理
このサブプロシージャでは、ListBoxに選択可能なカラムを表示します。BindAvailableListBoxは、Page_Loadイベントから呼ばれます。行78-80のIf…End Ifでは、得意先IDのカラムが選択されているか調べています。選択されていないときは、ListBoxのItemsコレクションのAdd()メソッドで得意先IDのカラムを追加します。後続するIf…End Ifでは、得意先名、担当者名、役職部署、電話番号、都道府県のカラムが選択されていないか調べてListBoxに追加します。
|
76: Sub
BindAvailableListBox() 81: If
mstrDisplayColumns.IndexOf("CompanyName") = -1 Then 95: End If |
Sub BindSelectedListBox()の処理
このプロシージャは、ListBoxに選択されているカラムを表示します。BindSelectedListBoxは、Page_Loadイベントから呼ばれます。
行100では、すでに選択されているカラムを分割して配列変数に格納します。行104-118のFor…Nextでは、配列変数からカラムを取り出してListBoxに追加します。カラムをListBoxに追加するには、ItemsコレクションのAdd()メソッドを使用します。Add()メソッドの引数には、ListItemを指定します。
|
99: Sub
BindSelectedListBox() 115: ElseIf
astrColumns(i) = "Ken" Then |
リスト PopupColumns.aspxのソースコード(コード編)
|
1: <%@ Page
language="vb" SmartNavigation="False" %> |
Note
|
DataGridにダイナミックに追加したカラムをPage_Loadイベントの前に復元するには DataGridにダイナミックに追加したカラムはVie ダイナミックに追加したカラムをPage_Loadイベントが発生する前に復元させるには、LoadVie 以下のサンプルでは、Session("DisplayColumns")変数に保存されているカラムをLoadVie Private Property DynamicColumnAdded() As Boolean Get If Vie Return False Else Return True End If End Get Set (ByVal Value As Boolean) Vie End Set End Property Protected Overrides Sub LoadVie
MyBase.LoadVie 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
|
DataGridにTemplateColumnをダイナミックに追加するには DataGridにTemplateColumnをダイナミックに追加するには、New TemplateColumn()でTemplateColumnのインスタンスを生成します。TemplateColumnのHeaderTextなどのプロパティは、BoundColumnと同じように設定することができます。ItemTemplateを生成するには、ItemTemplate専用のクラスを作成する必要があります。このサンプルでは、DynamicItemTemplateのクラスを作成してLabelコントロールに得意先名(CompanyName)をバインドしています。TemplateColumnのItemTemplateに、DynamicItemTemplateのインスタンスを設定したら、DataGridのColumnsコレクションのAdd()メソッドでTemplateColumnを追加します。 Dim tc1 As New TemplateColumn() With tc1 .HeaderText = "<div class='dgrdHeader'>得意先名</div>" .ItemTemplate = New DynamicItemTemplate() End With dgrdCustomers.Columns.Add(tc1) ItemTemplateのLabelにデータをバインドするには、AddHandlerでLabelにデータをバインドするイベントを登録する必要があります。BindLabelイベントでは、得意先名がNullか調べてNullのときは、LabelのTextプロパティに(Null)を設定します。Nullでないときは、DataItemから得意先名を取得してLabelのTextに設定します。これで、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 |