【WPF】DataGridをユーザーコントロール化しよう

当ページのリンクには広告が含まれています。

データを一覧形式で表示する事って結構よくあります。

こんな時に登場するのがDataGridなのですが、標準機能はシンプルなので、行番号の表示やCSV読み込み、クリップボードからの貼り付け、表示データの絞り込みや検索機能など、色々と付加してあげなければなりません。

そこで、よく使う機能を一通り実装したDataGridのユーザーコントロールを作ってみました。

あくまでもサンプルなので、みなさんの用途に合わせて自由に修正して使っていただければと思います。

目次

DataGridユーザーコントロールの概要

今回のユーザーコントロールはこんな感じのデザインです。

機能としては次の通りです。

  • イベントの発生(カレントセル移動、クリック、ダブルクリック、キー入力、データ表示)
  • 表示内容をクリップボードへコピー(コンテキストメニュー及びコントロール+V)
  • クリップボードの内容(CSV)を一覧へ張り付け(コンテキストメニュー及びコントロール+C)
  • 表示内容を全選択(コンテキストメニュー及びコントロール+A)
  • 指定条件による表示内容の絞り込み表示
  • カレントセルのある列に対して文字列を検索
  • 表示内容をCSVファイルへ書き込み(コンテキストメニュー)
  • CSVファイルの内容を読み込んで表示(コンテキストメニュー)
  • CSVファイルのドラッグ&ドロップによる表示

以前の記事で紹介したCsvUtilクラスが必要

CSVファイル読み込み、ファイル出力については、「【C#】CSVの読み込みと書き込みを部品化しました!」の記事で紹介しているCsvUtilクラスを利用しています。

このユーザーコントロールと一緒に、CsvUtilもご利用ください。

ダウンロード先

今回のソースコード一式は、こちらからダウンロード可能です。

デモプログラムに張り付けていますので、実際に絞り込みや検索機能をお試しいただけます。

デモプログラムの仕様については、こちら をご覧ください。

ソースコード

では、さっそくソースコードを見ていきます。

まずはXamlから。

続けて、C#のソースコードです。

使い方

使用可能なプロパティとイベントは次の通りです。

カテゴリ名前説明
プロパティDataSource表示対象のDataTable
プロパティFilter表示内容の絞り込み用フィルタ
イベントCurrentCellChangedカレントセルが変化した時に発生するイベント
イベントCellClickセルをクリックした時に発生するイベント
イベントCellDoubleClickセルをダブルクリックした時に発生するイベント
イベントCellKeyDownキー入力した時に発生するイベント
イベントGridDataBindingDataGridにDataTableの内容が表示された時に発生するイベント。
次の4つの操作のいずれかにより発生
①プログラムからDataSourceにDataTableを代入した時
②ファイルをGridにドラッグ&ドロップした時
③クリップボードからコントロール+CでGridに張り付けた時
④コンテキストメニューからCSVファイルを選択した時
メソッドExecContextMenuコンテキストメニューに割り当てられている機能を呼び出す

void ExecContextMenu(string function)

function:"AllSelect","Copy","Paste","Open","Save" から選択
メソッドFindNext現在のカレントセル位置から下方向に文字列を検索する

void FindNext(string value)

value:検索したい文字列
メソッドFindBack現在のカレントセル位置から上方向に文字列を検索する

void FindBack(string value)

value:検索したい文字列
メソッドGetCellValue指定した列と位置にあるセルの値を取得

object GetCellValue(DataGrid dataGridint rowNo,int columnNo)

rowNo:0から始まる行番号
columnNo:0から始まる列番号
メソッドSetCurrentCell指定した位置にカレントセルを設定し、その位置までスクロールする

void SetCurrentCell(int rowNo, int columnNo)

rowNo:0から始まる行番号
columnNo:0から始まる列番号
メソッドGetSelectedCellIndex選択されている先頭のセルを取得

(int rowNo, int columnNo) GetSelectedCellIndex()
メソッドGetCurrentCellIndex現在のカレントセルの行と列番号を取得

(int rowIndex, int columnIndex) GetCurrentCellIndex()
メソッドCreateDataTableFromClipboardクリップボードからCSVを読み込む

DataTable CreateDataTableFromClipboard(bool isHeader = true)

isHeader:1行目をヘッダーとして扱う場合 true

DataSourceプロパティ

表示したいDataTableは、このプロパティに代入します。

逆に表示中のDataTableを取り出すことも可能です。

このプロパティにDataTableを代入したタイミングで、DataTableのカラム名がDataGridに動的に追加され、DataTableの内容が表示されます。

Filterプロパティ

これは DataTable のDefaultView に対して Filter を渡すだけのプロパティです。

DefaultView は DataView 型なので、Filter の記述方法は DataView に準じます。

このプロパティを使わずに、 DataSource.DefaultView.RowFilter と言う風に記述しても同じことが出来ますが、少しでも記述を省略するために、あえてFilterというプロパティを作りました。

詳細は、「DataTableの基礎と使い方」の記事の目次から「データのフィルタリングとソート」へジャンプしてお読みください。 

= , <= , < , <> , > , > = , is null , like , not , and , or の演算子を使ってSQLみたいな記述が可能です。

カレント列の検索を行うFindNext,FindBackメソッド

カレントセルが無い状態だと検索機能が効かないようになっているので、検索したい列をあらかじめクリックしてください。

検索はカレントセルを基準に、FindNextで下方向、FindBack で上方向に検索します。

連続してメソッドを実行することで、次々に検索を行い、自動的にスクロールしてくれます。

そして、もうその方向にはヒットするセルが存在しない場合、カレントセルは移動しなようになっています。

「もうこれ以上見つかりません」みたいなメッセージを出すことも考えましたが、今のところはその仕様は入れていませんので、ほしい方はメッセージボックスを出すなりの修正を行って下さい。

コンテキストメニューをカスタマイズしたい場合

コンテキストメニューは、XamlとC#のExecContextMenuメソッドの2つから成り立っています。

単純に文言を変えるだけとか、いらないメニューを消したいだけなら、Xamlの修正でOKです。

もし新たにメニューを追加したい場合、XamlとC#の両方を変更します。

まず、Xamlにメニューを1つ追加し、CommandParameterに新たな機能の名前を指定します。

CommandParameterで指定した機能名が、下記のfunction に渡ってきますので、Switch文に処理を記述します。

イベント発生時のEventArgs について

マウスクリック、キー入力のイベント発生時に渡されるイベント引数(EventArgs)は、元のイベント引数を継承し、新たにクリックされた行番号、列番号、列名、セルの値が追加された形になっています。

例えば、セルをクリックした時、DataGridが受け取るイベントのイベント引数は MouseButtonEventArgsですが、それを継承したDataGridMouseEventArgsを作り、そこにRowIndex,ColumnIndex,ColumnName,Value を追加しています。

まとめ

今回は、標準のDataGridにいくつかの便利機能を加えた形で、ユーザーコントロールを作りました。

実際にこのユーザーコントロールを使う上では、例外処理など色々な考慮が必要になるとは思いますが、細かい部分は利用する方の仕様に合わせてカスタマイズして頂くか、ご自身のソースコードの参考にして頂ければと思います。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次