●DataGridの編集時、出荷日をCalendarから選択 (ch63DataGrid2.aspx)
DataGridの編集時、出荷日をテキストボックスに直接入力する代わりにカレンダーから選択できるように操作性を改善します。
このサンプルでは、以下のノウハウを習得することができます。
▼DataGridの編集行にCalendarを表示する方法
▼連結列をテンプレート列に変換する方法
▼テンプレートの編集からEditItemTemplateにCalendarコントロールを作成する方法
▼CalendarコントロールのSelectedDate、Visibleプロパティの使い方
▼Calendarコントロールからデフォルトの日付を選択する方法
▼DataGridの編集行からCalendarで選択した日付を取得する方法
▼DataGridItemオブジェクトのFindControlメソッドの使い方
1. 連結列をテンプレート列に変換
DataGrid1の右クリックから[プロパティビルダ]を選択します。「DataGrid1プロパティ」が表示されたら、左側から[列]を選択します。「選択された列」から[出荷日]を選択します。画面最下位の[この列をテンプレート列に変換する]をクリックして連結列をテンプレート列に変換します。「選択された列」の[出荷日]が連結列からテンプレート列に変わります。[OK]をクリックして「プロパティビルダ」を閉じます。

図 プロパティビルダの[列]から連結列をテンプレート列に変換する
2. テンプレートの編集
DataGrid1の右クリックから[テンプレートの編集]→[Columns[2] – 出荷日]を選択します。「DataGrid1 – Columns[2] – 出荷日」のテンプレート編集が表示されたら、EditItemTemplateのTextBoxの右クリックから[削除]を選択してTextBoxを削除します。ツールボックスの[Webフォーム]から、CalendarをドラッグしてEditItemTemplateにドロップします。

図 EditItemTemplateにCalendarをドラッグ&ドロップする

図 カレンダーの自動フォーマットから[シンプル]を選択する
プロパティウィンドウからCalendar1を選択したら、「(DataBindings)」プロパティを選択して
(iconEllipsis.gif)をクリックします。「Calendar1データ連結」が表示されたら、「連結可能プロパティ」から[SelectedDate]を選択します。[カスタム連結式]を選択したら、テキストボックスに以下の連結式を入力します。
Container.DataItem("ShippedDate")
同様の手順で、「連結可能プロパティ」から[VisibleDate]を選択します。[カスタム連結式]を選択したら、テキストボックスに以下の連結式を入力します。
Container.DataItem("ShippedDate")
最後に、[OK]をクリックして「データ連結」ダイアログを閉じます。

図 EditItemTemplateのCalendarのプロパティ設定
テンプレート編集の右クリックから[テンプレート編集の終了]を選択して終了します。
3. UpdateCommandイベントの書き換え
メニューバーから[表示]→[コード]を選択してコードビューに切り替えます。DataGrid1_UpdateCommandイベントを以下のように書き換えます。
Private Sub DataGrid1_UpdateCommand(ByVal source As Object,
ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
Handles DataGrid1.UpdateCommand
Dim calShippedDate As Calendar = CType(e.Item.FindControl("Calendar1"), Calendar)
Dim strShipName As String = CType(e.Item.Cells(1).Controls(0), TextBox).Text
Dim dtmShippedDate As DateTime = calShippedDate.SelectedDate
Dim intOrderID As Integer = DataGrid1.DataKeys(e.Item.ItemIndex)
UpdateRecord(strShipName, dtmShippedDate, intOrderID)
DataGrid1.EditItemIndex = -1
BindGrid()
End Sub
4. ブラウザに表示
ソリューションエクスプローラから[ch63DataGrid1.aspx]を右クリックしてブラウザに表示します。DataGridにOrders表が表示されたら、[編集]をクリックします。出荷先はテキストボックスに表示されますが、出荷日がカレンダーに表示されます。[更新]をクリックすると、カレンダーから選択した出荷日がOrders表に保存されます。

図 出荷日をカレンダーから選択する
■解説
DataGridの編集時に「出荷日」をCalendarから選択できるようにするには、連結列をテンプレート列に変換します。連結列をテンプレート列に変換するには、DataGrid1の右クリックから[プロパティビルダ]を選択します。「DataGrid1プロパティ」が表示されたら、左側から[列]を選択します。「選択された列」から[出荷日]を選択したら、画面最下位から[この列をテンプレート列に変換する]をクリックします。[OK]をクリックすると、以下のようなテンプレート列が生成されます。
<asp:DataGrid id="DataGrid1" runat="server"
AutoGenerateColumns="False">
<Columns>
・・・
<asp:TemplateColumn
HeaderText="出荷日">
<ItemTemplate>
<asp:Label runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.ShippedDate", "{0:d}") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.ShippedDate", "{0:d}") %>'>
</asp:TextBox>
</EditItemTemplate>
</asp:TemplateColumn>
・・・
</Columns>
</asp:DataGrid>
DataGridの右クリックから[テンプレートの編集]→[Columns[2] – 出荷日]を選択します。「DataGrid1 – Columns[2] – 出荷日」のテンプレート編集が表示されたら、EditItemTemplateからTextBoxを削除してCalendarを作成します。プロパティウィンドウから[Calendar1]を選択したら、「(DataBindings)」プロパティから「Calendar1データ連結」を表示します。「連結可能プロパティ」から[SelectedDate]と[VisibleDate]を選択したら、カスタム連結式を入力して出荷日(ShippedDate)をバインドします。テンプレートの編集の右クリックから[テンプレート編集の終了]を選択すると、以下のようなテンプレート列が生成されます。
<asp:TemplateColumn HeaderText="出荷日">
<ItemTemplate>
<asp:Label id=Label1 runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.ShippedDate", "{0:d}") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:Calendar id=Calendar1
runat="server"
SelectedDate='<%# Container.DataItem("ShippedDate") %>'
VisibleDate='<%# Container.DataItem("ShippedDate") %>'
・・・>
</asp:Calendar>
</EditItemTemplate>
</asp:TemplateColumn>
DataGridから[編集]をクリックすると、WebページがポストバックされてPage_Load→DataGrid1_EditCommandの順にイベントが発生します。Page_Loadイベントでは、IsPostBackプロパティを調べて初期ロードのときBindGridメソッドを実行します。
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
If Not IsPostBack Then
BindGrid()
End If
End Sub
BindGridメソッドは、CreateDataSetメソッドを実行してOrders表をDataSetに取り込みます。DataGridオブジェクトのDataSourceプロパティにDataSetオブジェクトを設定して、DataBindメソッドを実行してバインドします。
Private Sub BindGrid()
With DataGrid1
.DataSource = CreateDataSet("OrderPackage.GetOrders")
.DataKeyField = "OrderID"
.DataBind()
End With
End Sub
DataGrid1_EditCommandイベントは、DataGridオブジェクトのEditItemIndexプロパティにカレントのアイテム番号を設定して、BindGridメソッドを実行します。BindGridメソッドがDataGridにOrders表をバインドすると、Webページがポストバックされて出荷先がテキストボックス、出荷日がカレンダーに表示されます。このとき、[編集]ボタンは[更新]と[中止]ボタンに切り替わります。[更新]をクリックすると、Webページがポストバックされて、DataGrid1_UpdateCommandイベントが発生します。
Private Sub DataGrid1_EditCommand(ByVal source As Object,
ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
Handles DataGrid1.EditCommand
DataGrid1.EditItemIndex = e.Item.ItemIndex
BindGrid()
End Sub
DataGrid1_UpdateCommandイベントは、編集行から出荷日と出荷先を取得して変数に保存します。編集行から出荷日を取得するには、DataGridItemオブジェクトのFindControlメソッドを実行してCalendarコントロールを検索します。
UpdateRecordメソッドを実行してOrders表を更新します。UpdateRecordメソッドの引数には、出荷先、出荷日、受注IDを指定します。DataGridオブジェクトのEditItemIndexプロパティに「-1」を設定したら、BindGridメソッドを実行してOrders表をバインドします。DataGridの編集行が通常行として表示されます。
Private Sub DataGrid1_UpdateCommand(ByVal source As Object,
ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
Handles DataGrid1.UpdateCommand
Dim calShippedDate As Calendar = CType(e.Item.FindControl("Calendar1"), Calendar)
Dim strShipName As String = CType(e.Item.Cells(1).Controls(0), TextBox).Text
Dim dtmShippedDate As DateTime = calShippedDate.SelectedDate
Dim intOrderID As Integer = DataGrid1.DataKeys(e.Item.ItemIndex)
UpdateRecord(strShipName, dtmShippedDate, intOrderID)
DataGrid1.EditItemIndex = -1
BindGrid()
End Sub