かずきのBlog@hatena

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

ReactivePropertyを持つVMのコレクションをWindowsFormsのDataGridViewに表示する

遊びです。本気ではないので気を付けてください。

xin9leさんとチャットしながら作っててこんな拡張メソッドを用意しておけば。

public static class DataGridViewBindingExtensions
{
    public static void BindTo<TCollectionItem>(
        this IEnumerable<TCollectionItem> self, 
        DataGridView dgv,
        params Func<TCollectionItem, DataGridViewCell>[] createCells)
    {
        foreach (var item in self)
        {
            var row = new DataGridViewRow();
            row.Cells.AddRange(createCells.Select(x => x(item)).ToArray());
            dgv.Rows.Add(row);
        }

        dgv.CellEndEdit += (_, e) =>
            {
                var cell = dgv.Rows[e.RowIndex].Cells[e.ColumnIndex];
                IReactiveProperty rp = (IReactiveProperty)cell.Tag;
                rp.Value = cell.Value;
            };
    }


    public static TCell ToCell<TCell>(this IReactiveProperty self)
        where TCell : DataGridViewCell, new()
    {
        var cell = new TCell();
        cell.Value = self.Value;
        cell.Tag = self;
        return cell;
    }
}

こんな感じにDataGridViewに表示するコードが書けることがわかった。

var vm = new Form1ViweModel();
vm.People.BindTo(
    this.dataGridView1,
    x => x.Name.ToCell<DataGridViewTextBoxCell>(),
    x => x.Age.ToCell<DataGridViewTextBoxCell>());

DataGridViewには、あらかじめCellに対応するColumnを定義しておくこと。

本当に使えるかは置いておいて、こういうのを考えるのは楽しい。