今回の記事は、過去に掲載した記事『SQL Serverのデータをグリッド表示するWPFアプリケーションの作成』に、より細かいC1DataGridコントロールの使い方を加筆し、再構成しています。
はじめに
WPF対応のC1DataGridコントロールは、初めて使う方でもすぐにデータベースのデータをグリッド表示することができる扱いやすいコントロールです。しかも、グループ化や集計、フィルタ機能など高度な機能があらかじめ実装されているので、複雑で難しいコードを書く必要は一切ありません。また、WPF用コントロールなので、WPFの高度なデザイン性を生かしたアプリケーションを作成できます。
今回は、このC1DataGridコントロールを使い、SQL Server上のデータをグリッド表示するWPFアプリケーションを作ってみました。
対象読者
Visual Basic 2010/2012/2013、またはVisual C# 2010/2012/2013を使ってプログラムを作ったことがある人。
必要な環境
Visual Basic 2010/2012/2013、Visual C# 2010/2012/2013、Visual Studio 2010/2012/2013でプログラムが作れる環境。
なお、本プログラムは次の環境で開発・動作確認を行っています。
- OS:Windows 7
- 開発Tool:Visual Studio 2010、.NET Framework 4
プログラム実行時の注意事項
本稿の実行ファイル(バイナリファイル)を動かすには、zipファイルに同梱してある以下のファイルが必要になります。.NET Framework 4でのみご使用いただけます。
ファイル名 | 説明 |
---|---|
C1.WPF.4.dll | 本体アセンブリ |
C1.WPF.DataGrid.4.dll | 本体アセンブリ |
C1.WPF.DateTimeEditors.4.dll | 本体アセンブリ |
これらのファイルを、実行プログラムと同じフォルダに格納します。
なお、本サンプルプログラムの実行ファイルには、2つのバージョンがありますが、いずれも記事で紹介している内容を確認できます。
- DataGrid_WPF_vb.exe(行単位でカレントセルが移動するバージョン)
- DataGrid_WPF_vb enter key.exe(カレントセルをEnterキーで下方に移動させるバージョン)
コンポーネントのインストール
トライアル版は、グレープシティのWebページから申し込みできます。
トライアル申込フォームが表示されますので、必要情報を入力して申し込むとトライアル版のダウンロード手順を記載したE-Mailが送られてきます。その手順にそってダウンロードを行ってください。また、ダウンロードファイルは圧縮ファイルになっていますので、解凍してインストーラを起動します。
制限事項などの詳細については、インストーラに同梱されているリリースノートを参照ください。
コントロールと参照の追加
ComponentOne Studioをインストールしたら、プロジェクトにコントロールを追加します。ツールボックスに専用のタブを作成し、使用するコンポーネントを追加します。追加するコンポーネントは、アセンブリ名が「C1.WPF.DataGrid.4」の「C1DataGrid」コントロールです。
これらのコントロールを追加すると、プロジェクトに以下のランタイムライブラリへの参照が追加されます。
ファイル | 内容 |
---|---|
C1.WPF.4 | 本体アセンブリ |
C1.WPF.DataGrid.4 | 本体アセンブリ |
C1.WPF.DateTimeEditors | 本体アセンブリ |
また、プロジェクトに以下のランタイムライブラリが追加されます(.NET Framework 4が必要です)。
ファイル | 内容 |
---|---|
C1.WPF.4.dll | 本体アセンブリ |
C1.WPF.DataGrid.4.dll | 本体アセンブリ |
C1.WPF.DateTimeEditors.4.dll | 本体アセンブリ |
C1DataGridコントロールの概要
C1DataGridコントロールは、表形式データをWPFアプリケーションで簡単に表示、編集、分析することができるコントロールです。ADO.NETデータセットなどの、System.Collections.IEnumerableインターフェースを実装している任意のオブジェクトに対してデータ連結して、データの入力・編集を行うことが可能です。グリッドデータは、グループ化や集計、フィルタ機能などの高度な機能があらかじめ実装されているので、複雑で難しいコードを書く必要は一切ありません。
また、C1DataGridコントロールは、SilverlightとWPFで使用できる強力なグリッドコントロールで、オブジェクトモデルはMicrosoftのDataGridコントロールに基づいているため、C1DataGridコントロールに簡単に移行できます。
C1DataGridコントロールの特徴
C1DataGridコントロールは、以下のような特徴を持っています。
完全な対話式グリッド
エンドユーザーの使用感を高めるために、完全な対話式グリッドを作成します。列のサイズ変更と並べ替え、行の編集、ソート、フィルタ処理、グループ化、フリーズ、選択など多くの対話式機能が組み込まれています。
データのグループ化と集計
Outlookスタイルのグループ化をサポートします。列ヘッダーをグリッドの上にある領域にドラッグするだけでデータをグループ化できます。展開/折りたたみ可能なノードが自動的に生成されます。グループ化したヘッダー行に、集計関数の計算結果や合計を表示することも可能です。
Excel形式のフィルタ機能
デフォルトでは、Excel形式のフィルタ機能をサポートしています。このタイプのフィルタ機能では、各列でドロップダウンメニューを使用できるため、ユーザーはフィルタ条件を作成できます。
高パフォーマンス
行と列の両方を再利用することで(UIの仮想化)、大規模なデータセットを処理する際に最適なパフォーマンスを得ることができます。
複数の組み込みの列タイプ
C1DataGridコントロールには、多くの列エディタが組み込まれており、それによってすべての標準データ型をサポートすることができます。テキスト、チェックボックス、DateTimeピッカー、コンボボックス、および画像のためのエディタが組み込まれています。マスク付きテキスト、ハイパーリンク、複数行テキスト、カラーピッカーなどカスタムの列エディタから、必要なエディタを選択することも可能です。
RowDetailsTemplateおよび階層のサポート
C1DataGridコントロールでは、各行の折りたたみ可能なセクション内にUIElementsを埋め込むことができるRowDetailsTemplateテンプレートがサポートされています。例えば、別のDataGridを埋め込むだけで、マスター/詳細グリッドを作成して階層データを表示できます。
上端行テンプレートと下端行テンプレート
上端行テンプレートと下端行テンプレートを使用して、カスタム行をグリッドに簡単に作成および追加することができます。例えば、独自のフィルタの設計、合計行の指定、UIElementsの埋め込みなどを行うことが可能です。
複数選択モード
すべてのセル選択オプションをエンドユーザーに提供します。具体的には、単一セル、単一行、単一列、単一範囲、複数行、複数列、および複数範囲です。DataGrid for WPFコントロールはクリップボードをサポートするので、エンドユーザーは選択したセルをMicrosoft Excelなどの任意のテキストエディタに簡単に貼り付けることが可能です。
新規行
ユーザーは、グリッドの上部または下部のいずれかに空の新規行を表示することで、新規行をDataGrid for WPFに追加できます。
カスタム行とカスタム列
各DataGrid行に対して独自のデータテンプレートを設計し、複数のデータフィールドのデータを結合できる複合列を作成します。
ClearStyleを使って簡単に色を変更する
DataGrid for WPFは、ClearStyle技術(後述)をサポートしているため、色のプロパティをいくつか設定するだけで、グリッド全体のスタイルを簡単に設定できます。
ヘッダのセルを結合する場合や、複数行/複数列のヘッダを表示する場合は、ヘッダが通常の行/列と同等に扱われるため、ソートや移動、行/列の選択、フィルタリング、グループ化などの機能を利用することができません。
(参考:[DataGrid for WPF]結合されたヘッダや複数行/列のヘッダで、ソートやフィルタリングなどの機能を使用できない)
C1DataGridコントロールの外観の操作
C1DataGridコントロールは、一般的なテーブル書式設定オプション(1行ごとの背景色の変更、ヘッダーの表示/非表示、グリッド線、スクロールバーなど)をサポートしています。さらに、ブラシ、スタイル、およびテンプレートのプロパティで、コントロールとその行、列、ヘッダー、セルの外観を完全に変更できます。
行および列ヘッダーの表示/非表示の設定
デフォルトでは、行ヘッダーと列ヘッダーがグリッドに表示されます。ただし、必要に応じて、一方または両方のヘッダーを非表示に設定できます。そのためには、HeadersVisibilityプロパティを設定します。HeadersVisibilityプロパティには、次のオプションの一つを設定できます。
オプション | 説明 |
---|---|
None | 行ヘッダーと列ヘッダーの両方がグリッドで非表示になります。 |
Column | 列ヘッダーのみがグリッドに表示されます。 |
Row | 行ヘッダーのみがグリッドに表示されます。 |
All(デフォルト) | 列ヘッダーと行ヘッダーの両方がグリッドに表示されます。 |
グリッド線の表示/非表示の設定
デフォルトでは、垂直方向と水平方向のグリッド線がグリッドに表示されます。ただし、必要に応じて、一方または両方のグリッド線を非表示に設定できます。そのためには、GridLinesVisibilityプロパティを設定します。GridLinesVisibilityプロパティには、次のオプションの一つを設定できます。
オプション | 説明 |
---|---|
None | 水平方向と垂直方向の両方のグリッド線がグリッドで非表示になります。 |
Horizontal | 水平方向のグリッド線のみがグリッドに表示されます。 |
Vertical | 垂直方向のグリッド線のみがグリッドに表示されます。 |
All(デフォルト) | 水平方向と垂直方向の両方のグリッド線がグリッドに表示されます。 |
新規行の表示/非表示の設定
デフォルトでは、グリッドの末尾に新規追加行が配置されます。ただし、必要に応じてその位置の変更が可能です。そのためには、NewRowVisibilityプロパティを設定します。NewRowVisibilityプロパティには、次のオプションの一つを設定できます。
オプション | 説明 |
---|---|
Top | 新規追加行がグリッドの先頭に表示されます。 |
Bottom(デフォルト) | 新規追加行がグリッドの末尾に表示されます。 |
垂直および水平スクロールバーの表示/非表示の設定
デフォルトでは、グリッドの内容の高さまたは幅がグリッドのサイズを超えたときにのみ、グリッドの水平スクロールバーと垂直スクロールバーが表示されます。ただし、必要に応じて、スクロールバーを常に表示または非表示になるように設定したり、まったく無効になるように設定できます。そのためには、VerticalScrollbarVisibilityプロパティとHorizontalScrollbarVisibilityプロパティの設定が必要になります。VerticalScrollbarVisibilityプロパティとHorizontalScrollbarVisibilityプロパティには、次のオプションの一つを設定することができます。
オプション | 説明 |
---|---|
Disabled | 選択したスクロールバーは無効になります。 |
Auto(デフォルト) | 選択したスクロールバーは、グリッドの内容がグリッドウィンドウの大きさを超えるときだけ表示されます。 |
Hidden | 選択したスクロールバーは非表示になります。 |
Visible | 選択したスクロールバーは常に表示されます。 |
行の詳細の表示/非表示の設定
デフォルトでは、行の詳細は折りたたまれて表示されません。RowDetailsVisibilityModeプロパティを使用して、行の詳細を表示するかどうかと、いつ表示するかを設定できます。RowDetailsVisibilityModeプロパティには、次のオプションの一つを設定できます。
オプション | 説明 |
---|---|
VisibleWhenSelected | 行の詳細は選択されたときにのみ表示されます。 |
Visible | 行の詳細は常に表示されます。 |
Collapsed(デフォルト) | 行の詳細は折りたたまれて表示されません。 |
ブラシ
C1DataGridコントロールが提供するブラシの複数のプロパティを使用して、コントロールとその行、列、ヘッダー、セルの外観を完全に変更できます。次の表では、いくつかのブラシについて説明します。
ブラシ | 説明 |
---|---|
Background | レンダリング時に使用される背景ブラシを取得または設定します(このブラシは、データグリッドのすべてのパーツに適用されます)。 |
Foreground | レンダリング時に使用される前景ブラシを取得または設定します(このブラシは、データグリッドのすべてのパーツに適用されます)。 |
BorderBrush | レンダリング時に使用される境界線ブラシを取得または設定します(このブラシは、テーマに基づいて、データグリッドの一部のパーツに適用されます)。 |
SelectedBrush | 選択された行、行ヘッダー、列ヘッダーなどのレンダリング時に使用される、選択されたブラシを取得または設定します。 |
MouseOverBrush | マウスが行、行ヘッダー、列ヘッダーなどの上にあるときに使用される、マウスオーバーブラシを取得または設定します。 |
RowBackground | 行の背景ブラシを取得または設定します。 |
RowForeground | 行の前景ブラシを取得または設定します。 |
AlternatingRowBackground | 交互表示行の背景ブラシを取得または設定します。 |
AlternatingRowForeground | 交互表示行の前景ブラシを取得または設定します。 |
HorizontalGridLinesBrush | 水平線に適用されるブラシを取得または設定します。 |
VerticalGridLinesBrush | 垂直線に適用されるブラシを取得または設定します。 |
ClearStyle
C1DataGridコントロールは、コントロールのテンプレートを変更することなくコントロールの色を簡単に変更できる、ComponentOne Studio独自の新しいClearStyle技術をサポートします。
C1DataGridコントロールの配色を設定するC1DataGrid.Backgroundプロパティなど、いくつかのプロパティを設定するだけで、C1DataGridコントロールの外観を全面的に変更できます。塗りつぶしのオプションも、単色だけでなく2色のグラデーションを使用できます。
C1DataGridコントロールのデザイン時の設定
C1DataGridコントロールは、XAMLを使うことで多くの部位のデザインを自由にカスタマイズすることができます。
C1DataGridコントロールのセルの操作
C1DataGridコントロールでは、アプリケーションデザイン時により細かなセルの設定をすることができます。
セルの色の変更
デザイン時にセルの色を変更することができます。これはXAMLのコードを追加します。
まず、DataGridCellPresenterオブジェクトのスタイルを作成してBackground/Foregroundプロパティに変更したい色を設定します。
<Window.Resources> <Style x:Key="ColumnStyle" TargetType="c1:DataGridCellPresenter"> <Setter Property="Background" Value="DarkGray" /> <Setter Property="Foreground" Value="White" /> </Style> </Window.Resources>
次に色を変更したい列のCellStyleプロパティを作成し、そのスタイルに作成したスタイルを設定します。
<c1:C1DataGrid Name="c1DataGrid1" AutoGenerateColumns="False"> <c1:C1DataGrid.Columns> <c1:DataGridTextColumn Header="Column1" Binding="{Binding Column1, Mode=OneWay}" CellStyle="{StaticResource ColumnStyle}" /> </c1:C1DataGrid.Columns> </c1:C1DataGrid>
(参考:[DataGrid for WPF]セルの色を変更する方法は?)
セルの編集禁止
デザイン時にあらかじめセルの編集を禁止することができます。この操作は、列を明示的に定義して列のIsReadOnlyプロパティをTrueに設定します。
処理はXAMLにコードを追加します。
<c1:C1DataGrid Name="c1DataGrid1" AutoGenerateColumns="False"> <c1:C1DataGrid.Columns> <!--1列目のみ編集を禁止する--> <c1:DataGridTextColumn Header="Column1" Binding="{Binding Column1}" IsReadOnly="True" /> </c1:C1DataGrid.Columns> </c1:C1DataGrid>
(参考:[DataGrid for WPF]セルの編集を禁止する方法は?)
セルの枠線の色の操作
セルの枠線の色を変更することができます。
まず、DataGridCellPresenterオブジェクトのスタイルをリソースで作成し、BorderThickness/BorderBrushプロパティを設定します。
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="504" Width="955" xmlns:my="http://schemas.componentone.com/winfx/2006/xaml"> <Window.Resources> <Style x:Key="cellStyle" TargetType="my:DataGridCellPresenter"> <Setter Property="BorderBrush" Value="Red" /> <Setter Property="BorderThickness" Value="2" /> </Style> </Window.Resources>
次に、C1DataGrid.CellStyleプロパティに、作成したスタイルを設定します。
<Grid> <my:C1DataGrid CellStyle="{StaticResource cellStyle}" /> </Grid>
(参考:[DataGrid for WPF]セルの枠線の色を変更する方法は?)
セル内へのボタン表示が可能
C1DataGridコントロールでは、セル内にボタンを表示することができます。それには、DataGridTemplateColumn列を作成して、CellTemplateプロパティにボタンを設定するだけです。これは、以下のようなXAMLを記述します。
<c1:C1DataGrid Name="c1DataGrid1"> <c1:C1DataGrid.Columns> <c1:DataGridTemplateColumn> <c1:DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Content="ボタン" Click="Button_Click" /> </DataTemplate> </c1:DataGridTemplateColumn.CellTemplate> </c1:DataGridTemplateColumn> </c1:C1DataGrid.Columns> </c1:C1DataGrid>
また、このボタンをクリックした時の処理を作成することも可能です。
例えば、ボタンをクリックした時に行数を取得するには、ボタンのClickイベントハンドラでsenderの親(DataGridCellPresenter型)からボタンのオブジェクトを取得し、そのRow.Indexプロパティを参照して行数を取得します。この処理は、ビハインドコードに記述します。
Imports C1.WPF.DataGrid Private Sub Button_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Dim button = TryCast(sender, Button) Dim presenter = TryCast(button.Parent, DataGridCellPresenter) MessageBox.Show(presenter.Row.Index & "行目のボタン") End Sub
using C1.WPF.DataGrid; private void Button_Click(object sender, RoutedEventArgs e) { var button = sender as Button; var presenter = button.Parent as DataGridCellPresenter; MessageBox.Show(presenter.Row.Index + "行目のボタン"); }
(参考:[DataGrid for WPF]セルにボタンを表示する方法は?)
セル入力時のIMEモードが設定可能
セルへのデータ入力時に、テキストホックスのIMEモードのオンオフや入力する文字種を設定することができます。
セルでのIMEモードの自動起動は、C1DataGridコントロールの「BeganEdit」イベントハンドラで、編集用コントロールであるテキストボックスのIMEモードを設定します。この処理はビハインドコードで記述します。
例えば、セル編集開始時にIMEモードをカタカナに設定して自動起動するには、まずBeganEditイベントハンドラを定義します。次に、このイベントハンドラ内でInputMethodクラスのSetPreferredImeConversionModeメソッドを実行します。メソッドの引数にImeConversionModeValues列挙体のメンバを指定することで、起動時のIMEモードを選ぶことができます。
Public Sub New() nitializeComponent() AddHandler c1DataGrid1.BeganEdit, AddressOf c1DataGrid1_BeganEdit End Sub Private Sub c1DataGrid1_BeganEdit(sender As Object, e As C1.WPF.DataGrid.DataGridBeganEditEventArgs) If TypeOf e.EditingElement Is System.Windows.Controls.TextBox Then Dim txt As System.Windows.Controls.TextBox = DirectCast(e.EditingElement, System.Windows.Controls.TextBox) InputMethod.SetPreferredImeConversionMode(txt, ImeConversionModeValues.Katakana) InputMethod.SetPreferredImeState(txt, InputMethodState.[On]) End If End Sub
public MainWindow() { InitializeComponent(); c1DataGrid1.BeganEdit += c1DataGrid1_BeganEdit; } void c1DataGrid1_BeganEdit(object sender, C1.WPF.DataGrid.DataGridBeganEditEventArgs e) { if (e.EditingElement is System.Windows.Controls.TextBox) { var txt = ((System.Windows.Controls.TextBox)(e.EditingElement)); InputMethod.SetPreferredImeConversionMode(txt, ImeConversionModeValues.Katakana); InputMethod.SetPreferredImeState(txt, InputMethodState.On); } }
メンバー名 | 説明 |
---|---|
Alphanumeric | 英数字変換モードを使用します。 |
CharCode | 文字コード変換モードを使用します。 |
DoNotCare | どの入力変換方法を使用しても問題ありません。実際の変換方法は不確定です。 |
Eudc | EUDC(外字)変換モードを使用します。 |
Fixed | 固定変換モードを使用します。 |
FullShape | 全角変換モードを使用します。 |
Katakana | カタカナ変換モードを使用します。 |
Native | ネイティブ文字(ひらがな、ハングル、漢字)変換モードを使用します。 |
NoConversion | どの入力変換も実行しません。 |
Roman | ローマ字変換モードを使用します。 |
Symbol | 記号変換モードを使用します。 |
(参考:[DataGrid for WPF]編集中のセルにIMEモードを設定する方法)
(参考:[DataGrid for WPF]セルの編集用コントロールを取得する方法/イベントをハンドリングする方法)
マウスでクリックしたセルの値を取得する
アプリケーションによっては、マウスでクリックしたセルの値を取得したい場合があります。その場合は、各マウスクリックイベントでクリックされたセルの座標を取得し、その座標をGetCellFromPointメソッドに引き渡すことで、クリックしたセルを参照することができます。
次のコードは、セルをマウスで右クリックした時に、クリックされたセルの行列番号とその値をメッセージボックスで表示します。
まず、MouseRightButtonDownイベントハンドラを定義します。次に、そのイベントハンドラ内で引数eのGetPositionメソッドを使用してセルの座標を取得します。そして、その座標をC1DataGridコントロールのGetCellFromPointメソッドに渡すと、そのセルをDataGridCellオブジェクトとして返してきます。あとは、DataGridCellオブジェクトのプロパティを参照すれば、セルの行列番号や値を取得することができます。
Public Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 Me.C1DataGrid1.ItemsSource = newds.収穫量一覧 'クリックしたセルの取得 AddHandler C1DataGrid1.MouseRightButtonDown, AddressOf C1DataGrid1_MouseRightButtonDown End Sub 'クリックしたセルの取得 Private Sub C1DataGrid1_MouseRightButtonDown(sender As System.Object, e As System.Windows.Input.MouseButtonEventArgs) Dim wnd As Window = Window.GetWindow(Me) Dim point As Point = e.GetPosition(wnd) Dim cell As C1.WPF.DataGrid.DataGridCell = C1DataGrid1.GetCellFromPoint(point) If cell IsNot Nothing Then MessageBox.Show(String.Format("Cell Click [{0}, {1}]", cell.Row.Index, cell.Column.Index) & ":" & cell.Value) End If End Sub
public MainWindow() { InitializeComponent(); this.c1DataGrid1.ItemsSource = newds.収穫量一覧; // クリックしたセルの取得 c1DataGrid1.MouseRightButtonDown += c1DataGrid1_MouseRightButtonDown; } // クリックしたセルの取得 void c1DataGrid1_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { Window w = Window.GetWindow(this); Point point = e.GetPosition(w); C1.WPF.DataGrid.DataGridCell cell = c1DataGrid1.GetCellFromPoint(point); if (cell != null) { MessageBox.Show(String.Format("Cell Click [{0}, {1}]", cell.Row.Index, cell.Column.Index) + ":" + cell.Value); } }
(参考:[DataGrid for WPF]マウスでクリックされたセルを取得する方法)
ヘッダの設定
グリッドのヘッダに対するデザイン操作や機能に対してもカスタマイズすることができます。
列ヘッダのテキストの配置
列ヘッダの文字列の表示位置を設定するには、XAMLで列ヘッダのHeaderプロパティにTextBlockを配置して、TextBlockのHorizontalAlignment、VerticalAlignmentプロパティを設定します。
<c1:C1DataGrid Name="C1DataGrid1" AutoGeneratingColumn="C1DataGrid1_AutoGeneratingColumn"> <c1:C1DataGrid.Columns> <c1:DataGridTextColumn> <c1:DataGridTextColumn.Header> <TextBlock Text="列ヘッダ" HorizontalAlignment="Center" VerticalAlignment="Center" /> </c1:DataGridTextColumn.Header> </c1:DataGridTextColumn> </c1:C1DataGrid.Columns> </c1:C1DataGrid>
(参考:[DataGrid for WPF]列ヘッダのテキストの配置を設定する方法は?)
GUIの作成
では、さっそくアプリケーションを作成していきます。
このアプリケーションでは、SQL Serverのデータベースファイル「平成23年度秋冬野菜収穫量_Data.mdf」をC1DataGridコントロールに連結し、データをグリッドで表示します。また、オプションでグループ化が行えるようにしますので、フォームにはC1DataGridコントロールとCheckBoxコントロールを配置します。
コントロールの配置とデータベース連結
1. フォームにC1DataGridコントロールをドラッグアンドドロップし、適当なサイズに広げます。
2. Visual Studioのメニューから「データ-新しいデータソースの追加」を選びクリックします。「データソース構成ウィザード」が表示されます。
3. 「データベース」「データセット」を選び、「新しい接続」ボタンをクリックします。
「データソース」に「Microsoft SQL Server データベース ファイル(SqlClient)」を選び、「データベースファイル名」に「平成23年度秋冬野菜収穫量_Data.mdf」を選び、「テスト接続」ボタンをクリックして接続OKを確認します。
4. 続いてデータベースファイルをプロジェクトにコピーし、接続文字列を確認します。
5. テーブル「収穫量一覧」をクリックし、「完了」ボタンをクリックします。
6. C1DataGrid コントロールの上にCheckBoxコントロールを配置し、「Content」プロパティを「グループ化」に変更しClickイベントハンドラを作成します。
データベース連結処理
ここまでの作成で、C1DataGridコントロールとデータベースファイルが連結されましたので、データを取り出す処理をコードで作成します。
1. 2つの参照を設定します。一つは「C1.WPF.DataGrid」名前空間への参照で、もう一つは「データベースへの連結」で作成したテーブルアダプターです。
Imports C1.WPF.DataGrid Imports DataGrid_WPF_vb.平成23年度秋冬野菜収穫量_DataDataSetTableAdapters Class MainWindow
using C1.WPF.DataGrid; using DataGrid_WPF_cs.平成23年度秋冬野菜収穫量_DataDataSetTableAdapters; namespace DataGrid_WPF_cs { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window {
2. 次に、1つの変数とプロシージャ(C#はメソッド)「newds」の宣言を作成します。
Imports C1.WPF.DataGrid Imports DataGrid_WPF_vb.平成23年度秋冬野菜収穫量_DataDataSetTableAdapters Class MainWindow Inherits Window Private _newds As 平成23年度秋冬野菜収穫量_DataDataSet = Nothing Public ReadOnly Property newds() As 平成23年度秋冬野菜収穫量_DataDataSet
using C1.WPF.DataGrid; using DataGrid_WPF_cs.平成23年度秋冬野菜収穫量_DataDataSetTableAdapters; namespace DataGrid_WPF_cs { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { private 平成23年度秋冬野菜収穫量_DataDataSet _newds = null; public 平成23年度秋冬野菜収穫量_DataDataSet newds
3. この中に、クエリを実行してテーブルアダプターにデータを埋める式を記述します。
Public ReadOnly Property newds() As 平成23年度秋冬野菜収穫量_DataDataSet Get If _newds Is Nothing Then _newds = New 平成23年度秋冬野菜収穫量_DataDataSet Dim TA As New 収穫量一覧TableAdapter TA.Fill(_newds.収穫量一覧) End If Return _newds End Get End Property
public 平成23年度秋冬野菜収穫量_DataDataSet newds { get { if(_newds == null) { _newds = new 平成23年度秋冬野菜収穫量_DataDataSet(); 収穫量一覧TableAdapter TA = new 収穫量一覧TableAdapter(); TA.Fill(_newds.収穫量一覧); } return _newds; } }
4. 作成したプロシージャ(C#はメソッド)「newds」を、アプリケーション初期化のプロシージャ(C#はメソッド)で呼び出します。これで、アプリケーション起動時にグリッドにデータベースのデータが埋め込まれます。
Public Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 Me.C1DataGrid1.ItemsSource = newds.収穫量一覧 End Sub
public MainWindow() { InitializeComponent(); this.c1DataGrid1.ItemsSource = newds.収穫量一覧; }
5. アプリケーションを実行し、グリッドにデータが表示されていることを確認します。
グループ化の処理
続いて、グループ化の処理を作成します。グループ化とは、データを指定した列にある同じデータをグループにする機能です。
C1DataGridコントロールでは、CanUserGroupプロパティをTrueに設定すると、グリッドの上部にグループ化専用のエリアが表示され、ここに列名をドラッグアンドドロップするとグループ化が行われます。
今回は、CheckBoxコントロールのオンオフ機能を利用して、グループ化の有効・無効を切り替えます。
Private Sub CheckBox1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles CheckBox1.Click If CheckBox1.IsChecked = True Then C1DataGrid1.CanUserGroup = True Else C1DataGrid1.CanUserGroup = False End If End Sub
private void checkBox1_Click(object sender, RoutedEventArgs e) { if(checkBox1.IsChecked ==true) { c1DataGrid1.CanUserGroup = true; }else { c1DataGrid1.CanUserGroup = false; } }
また、セルをクリックするとソート機能が働き、セルをダブルクリックするとそのまま数値を変更できる数値入力ボックスが使え、列見出しをクリックするとフィルタ機能が使えるようになっています。
外観の変更
ここまでで、データベースのデータをグリッドで表示でき、グループ化機能も使えるようになりました。あとは、カラーをカスタマイズして見栄えのよい表になるように仕上げます。
今回変更する部位は次のとおりです。
プロパティ | 設定値 | 説明 |
---|---|---|
GroupingPanelBackground | #FFBB1CC7, #FFE7A9EB | グループ化領域の背景色(グラデーション) |
GroupingPanelForeground | White | グループ化領域の前景色 |
HeaderBackground | BlueViolet | ヘッダー領域の背景色 |
HeaderForeground | White | ヘッダー領域の前景色 |
MouseOverBrush | #FFEBDF33 | マウスホバー時の背景色 |
SelectedBackground | #FFF86060 | 選択したセルの背景色 |
では、GroupingPanelBackgroundプロパティのグラデーション設定を行ってみます。他のプロパティも同じ操作でカラーパレットを使って変更します。
1. プロパティウィンドウで、GroupingPanelBackgroundプロパティの値欄にある「▼」ボタンをクリックします。
2. カラーパレットが表示されます。デフォルトでは単色モードになっていますので、単色の場合はここで色を作成します。左下にはカラー名で色を選べるリストボックスがあります。カラーピッカーも備えていますので、フォーム上の色を取り出して使うこともできます。
3. グラデーションを作成する場合は、左上の「グラデーションブラシ」アイコンをクリックします。2色をブレンドするツールが表示されます。
4. 開始色のポインタをクリックし、色を選びます。
5. 終了色のポインタをクリックし、色を選びます。
このようにして、他のプロパティも色を設定していきます。
なお、行の交互表示の色が、デフォルトではVBとC#で違っています。この交互表示の色を変更したい場合は、「AlternatingRowBackground」プロパティを使用してください。
Enterキーでのカレントセルの移動
C1DataGridコントロールは、表のようにデフォルトではキーボードの矢印キーを使ってカレントセルを移動できるようになっていますが、これをEnterキーを使ってカレントセルを移動するように変更できます。
例えば、Enterキーを押した際に下のセルにカレントセルを移動するには、DataGridのKeyDownイベントでCurrentRowロパティの設定をする必要があります。
処理はビハインドコードに作成します。
まずc1DataGrid1_KeyDownイベントハンドラを定義します。次に、そのイベントハンドラの中で、現在のカレントセルの行番号を取得し、Enterキーが押されたら行方向にカレントセルを移動させます。現在のカレントセルの行番号を取得するには、SelectedIndexプロパティを使用します。
そして、カレントセルを次の行に移動させるには、CurrentRowプロパティに現在のカレントセルの行番号に1を加えた値を設定します。
なお、このコードを実行すると、カレントセルの移動が行単位からセル単位に替わります。
Public Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 Me.C1DataGrid1.ItemsSource = newds.収穫量一覧 'Enterキーによるカレントセルの移動 Me.C1DataGrid1.SelectionMode = C1.WPF.DataGrid.DataGridSelectionMode.MultiRange AddHandler Me.C1DataGrid1.KeyDown, AddressOf c1DataGrid1_KeyDown End Sub 'Enterキーによるカレントセルの移動 Private Sub c1DataGrid1_KeyDown(sender As Object, e As System.Windows.Input.KeyEventArgs) If e.Key = System.Windows.Input.Key.Enter Then e.Handled = True If C1DataGrid1.SelectedIndex <> C1DataGrid1.Rows.Count - 1 Then '現在のカレントセルの行番号を取得 Dim r As Integer = C1DataGrid1.SelectedIndex + 1 ' カレント行変更 C1DataGrid1.CurrentRow = C1DataGrid1.Rows(r) ' 選択範囲変更 C1DataGrid1.Selection.Clear() C1DataGrid1.Selection.Add(C1DataGrid1(C1DataGrid1.CurrentRow.Index, C1DataGrid1.CurrentColumn.Index)) ' スクロール設定 C1DataGrid1.ScrollIntoView(r, 0) End If End If End Sub
public MainWindow() { InitializeComponent(); this.c1DataGrid1.ItemsSource = newds.収穫量一覧; // Enterキーによるカレントセルの移動 this.c1DataGrid1.SelectionMode = C1.WPF.DataGrid.DataGridSelectionMode.MultiRange; this.c1DataGrid1.KeyDown += c1DataGrid1_KeyDown; } // Enterキーによるカレントセルの移動 void c1DataGrid1_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) { if (e.Key == System.Windows.Input.Key.Enter) { e.Handled = true; if (c1DataGrid1.SelectedIndex != c1DataGrid1.Rows.Count - 1) { //現在のカレントセルの行番号を取得 var r = ++c1DataGrid1.SelectedIndex; // カレント行変更 c1DataGrid1.CurrentRow = c1DataGrid1.Rows[r]; // 選択範囲変更 c1DataGrid1.Selection.Clear(); c1DataGrid1.Selection.Add(c1DataGrid1[c1DataGrid1.CurrentRow.Index, c1DataGrid1.CurrentColumn.Index]); // スクロール設定 c1DataGrid1.ScrollIntoView(r, 0); } } }
キーの組み合わせ | 説明 |
---|---|
↓ | フォーカスを現在のセルの真下のセルに移動します。フォーカスが最後の行にある場合は、[↓]キーを押してもフォーカスは移動しません。 |
↑ | フォーカスを現在のセルの真上のセルに移動します。フォーカスが最初の行にある場合は、[↑]キーを押してもフォーカスは移動しません。 |
← | フォーカスを行内の前のセルに移動します。フォーカスが行の最初のセルにある場合は、[←]キーを押してもフォーカスは移動しません。 |
→ | フォーカスを行内の次のセルに移動します。フォーカスが行の最後のセルにある場合は、[→]キーを押してもフォーカスは移動しません。 |
Home | フォーカスを現在の行内の最初のセルに移動します。 |
End | フォーカスを現在の行内の最後のセルに移動します。 |
Page Down | コントロールを表示されている行数分下にスクロールします。フォーカスは、最後に表示されている行の同じ列に移動します。最後の行の一部が表示されていない場合は、最後の行が完全に表示されるまでグリッドがスクロールします。 |
Page Up | コントロールを表示されている行数分上にスクロールします。フォーカスは、最初に表示されている行の同じ列に移動します。最初の行の一部が表示されていない場合は、最初の行が完全に表示されるまでグリッドがスクロールします。 |
Tab |
現在のセルが編集モードにある場合は、フォーカスを現在の行の次の編集可能なセルに移動します。フォーカスがすでに行の最後のセルにある場合は、実行された変更をコミットし、フォーカスを次の行の最初の編集可能なセルに移動します。フォーカスがコントロールの最後のセルにある場合は、フォーカスを親コンテナのタブオーダーで次のコントロールに移動します。 現在のセルが編集モードにない場合は、フォーカスを親コンテナのタブオーダーで次のコントロールに移動します。 |
Shift+Tab |
現在のセルが編集モードにある場合は、フォーカスを現在の行の前の編集可能なセルに移動します。フォーカスがすでに行の最初のセルにある場合は、実行された変更をコミットし、フォーカスを前の行の最後のセルに移動します。フォーカスがコントロールの最初のセルにある場合は、フォーカスを親コンテナのタブオーダーで前のコントロールに移動します。 現在のセルが編集モードにない場合は、フォーカスを親コンテナのタブオーダーで前のコントロールに移動します。 |
Ctrl+↓ | フォーカスを現在の列内の最後のセルに移動します。 |
Ctrl+↑ | フォーカスを現在の列内の最初のセルに移動します。 |
Ctrl+→ | フォーカスを現在の行内の最後のセルに移動します。 |
Ctrl+← | フォーカスを現在の行内の最初のセルに移動します。 |
Ctrl+Home | フォーカスをコントロール内の最初のセルに移動します。 |
Ctrl+Page Down | Page Down と同じです。 |
Ctrl+Page Up | Page Up と同じです。 |
Enter | 選択されたセルで編集モードに入るか、編集モードを終了します(グリッドと列の IsReadOnly プロパティが False の場合)。 |
F2 | 選択されたセルで編集モードに入ります(グリッドと列の IsReadOnly プロパティが False の場合)。フォーカスが新規行にある場合、新規行の最初の編集可能なセルの編集を開始します。 |
Esc | セルまたは新規行の編集をキャンセルします。 |
Del | 選択された行を削除します。 |
Insert | 新規行までスクロールし、編集を開始します。 |
(参考:[DataGrid for WPF]Enterキーによるカレントセルの移動方法)
その他のテクニック
日付の表示・編集を和暦で行う
日付を和暦で表示する場合は.NETのJapaneseCalendarクラスを使用します。DataGridで使用する場合は、日付を和暦に変換する値コンバーターを定義しておき、BindingオブジェクトのConverterプロパティに設定します。
また、非編集時だけでなく、編集時にも和暦を扱う場合は入力に使用するエディタコントロールが和暦をサポートする必要があるため、DataGridでTemplateColumnを使用し、編集時に使用するエディタをカスタマイズして和暦による編集を可能にする方法があります。
和暦を使う場合は、まず、日付を和暦に変換する値コンバーターをリソースで定義します。
<Window.Resources> <local:JapaneseCalendarConverter x:Key="jpConverter" /> </Window.Resources>
次に、このリソースを和暦を使いたい列にバインドします。
<c1:C1DataGrid AutoGenerateColumns="False" Name="C1DataGrid1"> <c1:C1DataGrid.Columns> <c1:DataGridDateTimeColumn Header="入社日付" Binding="{Binding i, Converter={StaticResource jpConverter}}" DateFormat="Long" /> <c1:DataGridTemplateColumn Header="入社日付(和暦入力)"> <c1:DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding i, Converter={StaticResource jpConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center" /> </DataTemplate>
(参考:[DataGrid for WPF]日付の表示・編集を和暦で行うには?)
漢字を正しい順序でソートする
C1DataGridや標準のDataGridのソート機能は、PagedCollectionViewクラスの仕様に依存し、WPFではソートや文字列比較の結果はカルチャに依存します。
PagedCollectionViewクラスでは、Cultureプロパティでソート処理に使用するCultureInfoを設定しますが、Cultureプロパティの既定値はnullであるため、日本語のソートが正常に行われない場合があります。
従って、漢字が正しい順序でソートされない場合は、次のようにPagedCollectionView.Cultureプロパティに日本語を設定して、データソースにPagedCollectionViewを設定することで、漢字などの日本語を正常な順序でソートすることができます。
日本語のWindowsの場合は、CultureInfoクラスのCurrentCulture プロパティが日本語として設定されていますので、このプロパティの値をPagedCollectionViewオブジェクトのCultureプロパティに設定します。
Dim view = New PagedCollectionView(list) view.Culture = CultureInfo.CurrentCulture c1DataGrid1.ItemsSource = view
var view = new PagedCollectionView(list); view.Culture = CultureInfo.CurrentCulture; c1DataGrid1.ItemsSource = view;
(参考:[DataGrid for WPF]漢字が正しい順序でソートされない)
チェックボックス列でチェック時のイベントを発生させる
チェックボックス型列において、チェックボックスのOn/Off切り替え時のイベントを取得するには、編集時のチェックボックスエディタのCheckedおよびUnchechedイベントを使用します。
<Style TargetType="CheckBox"> <Setter Property="Tag" Value="{Binding Name, Mode=OneWay}" /> <EventSetter Event="Checked" Handler="CheckBox_Checked" /> <EventSetter Event="Unchecked" Handler="CheckBox_Unchecked" /> </Style>
そして、ビハインドコードにイベントハンドラを作成し処理を記述します。
Private Sub CheckBox_Checked(sender As Object, e As Windows.RoutedEventArgs) If TypeOf sender Is CheckBox Then Me.textBlock1.Text = CType(sender, CheckBox).Tag + "のチェックがOnになりました" End If End Sub Private Sub CheckBox_Unchecked(sender As Object, e As Windows.RoutedEventArgs) If TypeOf sender Is CheckBox Then Me.textBlock1.Text = CType(sender, CheckBox).Tag + "のチェックがOffになりました" End If End Sub
private void CheckBox_Checked(object sender, System.Windows.RoutedEventArgs e) { if (sender is CheckBox) { this.textBlock1.Text = ((CheckBox)sender).Tag + "のチェックがOnになりました"; } } private void CheckBox_Unchecked(object sender, System.Windows.RoutedEventArgs e) { if (sender is CheckBox) { this.textBlock1.Text = ((CheckBox)sender).Tag + "のチェックがOffになりました"; } }
(参考:[DataGrid for WPF]チェックボックス列でチェック時のイベントを発生させる方法)
まとめ
C1DataGridコントロールは、このようにデータベース構成ウィザードの簡単な操作でデータベースとの連結が可能で、ソート、フィルタ処理、グループ化などの機能がすでに組み込まれていますので、コードを書かずにこれらの機能をすぐに使えることができます。
連結できるデータベースの種類も豊富なので、WPF独特のデザイン性の高さと組み合わせれば、視覚性の高いグリッドアプリケーションが作れるのではないでしょうか。