かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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を定義しておくこと。

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