i++

プログラム系のメモ書きなど

WPF/XAML : DataGrid にボタンの列を追加する

DataGrid のセル中に自分で定義した UI 要素を入れられる DataGridTemplateColumn という汎用的な列を定義し、その DataGridTemplateColumn.CellTemplate -> DataTemplate の中に Button を指定します。

サンプル

f:id:tkyjhr:20150821002203p:plain

DataGrid に DataGridTemplateColumn を置き、その中の Buttuon の IsEnabled を Bind したデータのプロパティでコントロールしたサンプルです。Bind の仕方は DataGridTextColumn などを使う場合と変わらないので、DataGridTemplateColumn の書き方さえ覚えれば問題ないと思います。

また、Button の Tag に "{Binding}" を指定することで、クリックイベント時にその行にバインドされたデータそのものを取得できるようにしています。

<DataGrid x:Name="MyDataGrid" Height="300" AutoGenerateColumns="False" CanUserAddRows="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
        <DataGridTemplateColumn Header="Action">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Content="Act" Click="Act_Click" Tag="{Binding}" IsEnabled="{Binding Actionable}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

変わったことはしていませんが、一応、cs 側のソースコードも載せておきます。 ごく簡単なサンプルなので クリック時の sender や Tag のキャスト失敗のチェックはしていません。

class SampleData
{
    public string Name { get; set; }
    public bool Actionable { get; set; }

    public SampleData(string name, bool actionable)
    {
        Name = name;
        Actionable = actionable;
    }
}

private ObservableCollection<SampleData> SampleDataCollection;

public MainWindow()
{
    InitializeComponent();

    SampleDataCollection = new ObservableCollection<SampleData>()
    {
        new SampleData("一郎", true),
        new SampleData("二郎", false),
        new SampleData("三郎", true)
    };

    MyDataGrid.ItemsSource = SampleDataCollection;
}

private void Act_Click(object sender, RoutedEventArgs e)
{
    Console.WriteLine((((Button)sender).Tag as SampleData).Name);
}