SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ComponentZine(ComponentOne)

SQL Serverのデータをグリッド表示するWPFアプリケーションの作成【増補改訂版】

ComponentOne Studioを活用したWindowsフォームアプリケーションの作成

  • このエントリーをはてなブックマークに追加

 「ComponentOne Studio」に含まれるWPF対応のC1DataGridコントロールを使って、SQL Server上のデータをグリッド表示するWPFアプリケーションを作ってみます。

  • このエントリーをはてなブックマークに追加
補足

 今回の記事は、過去に掲載した記事『SQL Serverのデータをグリッド表示するWPFアプリケーションの作成』に、より細かいC1DataGridコントロールの使い方を加筆し、再構成しています。

はじめに

 WPF対応のC1DataGridコントロールは、初めて使う方でもすぐにデータベースのデータをグリッド表示することができる扱いやすいコントロールです。しかも、グループ化や集計、フィルタ機能など高度な機能があらかじめ実装されているので、複雑で難しいコードを書く必要は一切ありません。また、WPF用コントロールなので、WPFの高度なデザイン性を生かしたアプリケーションを作成できます。

 今回は、このC1DataGridコントロールを使い、SQL Server上のデータをグリッド表示するWPFアプリケーションを作ってみました。

マウスホバー行・選択行などをカラフルなグリッドで表示
マウスホバー行・選択行などをカラフルなグリッドで表示
グループ化やその場での数値入力機能をあらかじめ実装
グループ化やその場での数値入力機能をあらかじめ実装
セルをマウスの右ボタンでクリックするとセルの位置と内容をメッセージボックスで表示
セルをマウスの右ボタンでクリックするとセルの位置と内容をメッセージボックスで表示
Enterキーでカレントセルを移動できる
Enterキーでカレントセルを移動できる

対象読者

 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.DataGrid.4」の「C1DataGrid」コントロールを選択する@@
アセンブリ名が「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行ごとの背景色の変更、ヘッダーの表示/非表示、グリッド線、スクロールバーなど)をサポートしています。さらに、ブラシ、スタイル、およびテンプレートのプロパティで、コントロールとその行、列、ヘッダー、セルの外観を完全に変更できます。

C1DataGridコントロールの各部位の名称
C1DataGridコントロールの各部位の名称

行および列ヘッダーの表示/非表示の設定

 デフォルトでは、行ヘッダーと列ヘッダーがグリッドに表示されます。ただし、必要に応じて、一方または両方のヘッダーを非表示に設定できます。そのためには、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プロパティを参照して行数を取得します。この処理は、ビハインドコードに記述します。

Visual Basic
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
C#
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モードを選ぶことができます。

Visual Basic
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
C#
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);
    }
}
ImeConversionModeValues列挙体のメンバ
メンバー名 説明
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オブジェクトのプロパティを参照すれば、セルの行列番号や値を取得することができます。

Visual Basic
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
C#
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を確認します。

「テスト接続」ボタンをクリックして接続OKを確認
「テスト接続」ボタンをクリックして接続OKを確認

 4. 続いてデータベースファイルをプロジェクトにコピーし、接続文字列を確認します。

 5. テーブル「収穫量一覧」をクリックし、「完了」ボタンをクリックします。

テーブル「収穫量一覧」をクリックし、「完了」ボタンをクリック
テーブル「収穫量一覧」をクリックし、「完了」ボタンをクリック

 6. C1DataGrid コントロールの上にCheckBoxコントロールを配置し、「Content」プロパティを「グループ化」に変更しClickイベントハンドラを作成します。

データベース連結処理

 ここまでの作成で、C1DataGridコントロールとデータベースファイルが連結されましたので、データを取り出す処理をコードで作成します。

 1. 2つの参照を設定します。一つは「C1.WPF.DataGrid」名前空間への参照で、もう一つは「データベースへの連結」で作成したテーブルアダプターです。

Visual Basic
Imports C1.WPF.DataGrid
Imports DataGrid_WPF_vb.平成23年度秋冬野菜収穫量_DataDataSetTableAdapters

Class MainWindow
C#
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」の宣言を作成します。

Visual Basic
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
C#
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. この中に、クエリを実行してテーブルアダプターにデータを埋める式を記述します。

Visual Basic
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
C#
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#はメソッド)で呼び出します。これで、アプリケーション起動時にグリッドにデータベースのデータが埋め込まれます。

Visual Basic
Public Sub New()
    ' この呼び出しはデザイナーで必要です。
    InitializeComponent()

    ' InitializeComponent() 呼び出しの後で初期化を追加します。

     Me.C1DataGrid1.ItemsSource = newds.収穫量一覧

End Sub
C#
public MainWindow()
    {
        InitializeComponent();
        this.c1DataGrid1.ItemsSource = newds.収穫量一覧;
    }

 5. アプリケーションを実行し、グリッドにデータが表示されていることを確認します。

アプリケーション実行結果
アプリケーション実行結果

グループ化の処理

 続いて、グループ化の処理を作成します。グループ化とは、データを指定した列にある同じデータをグループにする機能です。

 C1DataGridコントロールでは、CanUserGroupプロパティをTrueに設定すると、グリッドの上部にグループ化専用のエリアが表示され、ここに列名をドラッグアンドドロップするとグループ化が行われます。

 今回は、CheckBoxコントロールのオンオフ機能を利用して、グループ化の有効・無効を切り替えます。

Visual Basic
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
C#
private void checkBox1_Click(object sender, RoutedEventArgs e)
{
    if(checkBox1.IsChecked ==true)
    {
        c1DataGrid1.CanUserGroup = true;
    }else
    {
        c1DataGrid1.CanUserGroup = false;
    }
}
CheckBoxコントロールをクリックするとグループ化の領域が表示される
CheckBoxコントロールをクリックするとグループ化の領域が表示される
この領域に列名「地方名」をドラッグアンドドロップすると
この領域に列名「地方名」をドラッグアンドドロップすると
データが地方名でグループ化される
データが地方名でグループ化される

 また、セルをクリックするとソート機能が働き、セルをダブルクリックするとそのまま数値を変更できる数値入力ボックスが使え、列見出しをクリックするとフィルタ機能が使えるようになっています。

セルをダブルクリックすると数値入力ボックスが使えるようになる
セルをダブルクリックすると数値入力ボックスが使えるようになる
列見出しをクリックするとフィルタ機能が使える
列見出しをクリックするとフィルタ機能が使える

外観の変更

 ここまでで、データベースのデータをグリッドで表示でき、グループ化機能も使えるようになりました。あとは、カラーをカスタマイズして見栄えのよい表になるように仕上げます。

 今回変更する部位は次のとおりです。

プロパティ 設定値 説明
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を加えた値を設定します。

 なお、このコードを実行すると、カレントセルの移動が行単位からセル単位に替わります。

Visual Basic
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
C#
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プロパティに設定します。

Visual Basic
Dim view = New PagedCollectionView(list)
view.Culture = CultureInfo.CurrentCulture
c1DataGrid1.ItemsSource = view
C#
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>

 そして、ビハインドコードにイベントハンドラを作成し処理を記述します。

Visual Basic
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
C#
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独特のデザイン性の高さと組み合わせれば、視覚性の高いグリッドアプリケーションが作れるのではないでしょうか。

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/8490 2015/02/27 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング