かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

WPF4.5入門 その23 「DataGridコントロール その1」

過去記事

一か月ぶりくらいの更新です。忘れてたわけじゃなくてお仕事が忙しかったので気力がなくなってただけなのでマイペースで進んでいこうと思います。




DataGridコントロール

ということで今回はデータを表示する系のコントロールの代表格のDataGridコントロールです。DataGridコントロールは、WPFで表形式のデータを表示するためのコントロールです。WPFの柔軟なレイアウトシステムとテンプレートを使うことで以下のような表示を行うことができます。

WPFのDataGridは行と列からなる格子状のエリアに、ItemsSourceプロパティに設定されたコレクションの1要素を1行として表示します。1行を表示するときに、予め定義した列の表示の設定に従いセルにデータを表示していきます。また、DataGridにはデフォルトで表示する要素の型のプロパティから自動的に列を生成する機能があります。

列の自動生成機能

ここでは、DataGridの列の自動生成機能を使ってデータの表示を行います。WPFアプリケーションのプロジェクトのWindowに以下のようにDataGridを置きます。

<Window x:Class="DataGridSample02.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid Name="dataGrid" />
    </Grid>
</Window>

そして、DataGridに表示するためのデータを格納するPersonクラスを作成します。

namespace DataGridSample02
{
    // 性別
    public enum Gender
    {
        None,
        Men,
        Women
    }
 
    // DataGridに表示するデータ
    public class Person
    {
        public string Name { get; set; }
        public Gender Gender { get; set; }
        public int Age { get; set; }
        public bool AuthMember { get; set; }
    }
}

string型、enum型、int型、bool型のプロパティを持っています。このクラスのリストをMainWindowクラスのコンストラクタで設定します。

public MainWindow()
{
    InitializeComponent();
    // 適当なデータ100件生成する
    var data = new ObservableCollection<Person>(
        Enumerable.Range(1, 100).Select(i => new Person
        {
            Name = "田中 太郎" + i,
            Gender = i % 2 == 0 ? Gender.Men : Gender.Women,
            Age = 20 + i % 50,
            AuthMember = i % 5 == 0
        }));
    // DataGridに設定する
    this.dataGrid.ItemsSource = data;
}

ここで使用しているObservableCollection型は、DataGridなどのWPFのリストを表示するコントロールと、要素の追加・削除を同期するINotifyColletionChangedインターフェースを実装したクラスです。性能の問題など特別な理由がない限りこのクラスを利用すると便利です。
このプログラムを実行すると、以下のようなWindowが表示されまs。

プロパティに対応した列が生成されていることが確認できます。string型とint型の列は通常のテキストを表示する列が生成され、enum型はドロップダウンリストを表示する列が生成され、bool型にはチェックボックスを表示する列が生成されます。単にデータを表示するだけなら、このような自動生成の機能を利用することができます。

自動生成のカスタマイズ

DataGridの列の自動生成は、列を自動生成するタイミングで発生するAutoGeneratingColumnイベントである程度カスタマイズすることが出来ます。AutoGeneratingColumnイベント引数のDataGridAutoGeneratingColumnEventArgsクラスには以下のようなプロパティが定義されています。

プロパティ 説明
string PropertyName { get; } 列を生成するプロパティの名前を取得します。
bool Cancel { get; set; } 列の生成をキャンセルする場合はtrueを設定します。
DataGridColumn Column { get; set; } 自動生成される列を取得します。また、このプロパティに自分で作成したDataGridColumnの派生クラス(http://msdn.microsoft.com/ja-jp/library/vstudio/system.windows.controls.datagridcolumn(v=vs.110).aspx)を設定することで、自動生成するカラムを置き換えることが出来ます。

自動生成のカスタマイズの例として、先ほどの自動生成のプログラムのDataGridにAutoGeneratingColumnイベントハンドラを作成し下記のように記述しました。

private void dataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    // プロパティ名をもとに自動生成する列をカスタマイズします
    switch (e.PropertyName)
    {
        case "Name":
            // Name列は最初に表示してヘッダーを名前にする
            e.Column.Header = "名前";
            e.Column.DisplayIndex = 0;
            break;
        case "Age":
            // Ageプロパティは1番目に表示してヘッダーを年齢にする
            e.Column.Header = "年齢";
            e.Column.DisplayIndex = 1;
            break;
        case "Gender":
            // Genderプロパティは表示しない
            e.Cancel = true;
            break;
        case "AuthMember":
            // AuthMemberプロパティは2番目に表示してヘッダーを承認済みにする
            e.Column.Header = "承認済み";
            e.Column.DisplayIndex = 2;
            break;
        default:
            throw new InvalidOperationException();
    }
}

上記の変更をしてプログラムを実行すると下図のような結果になります。

カラムヘッダーがカスタマイズできていることと、Genderプロパティの列が生成されていないことが確認できます。