Custom DataGrid column with a CellTemplate and bin

2020-03-04 04:59发布

I need to create a reusable DataGrid column with a custom CellTemplate. This CellTemplate should, among other things, contain a TextBlock control to which I need to bind values to display in the DataGrid. All examples I've seen so far specified the CellTemplate for a column directly when using it in a DataGrid's Columns property and also specified a Binding directly to the TextBlock, e.g.:

<data:DataGrid>
    <data:DataGrid.Columns>
        <data:DataGridTemplateColumn Header="Name">
            <data:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </data:DataGridTemplateColumn.CellTemplate>
        </data:DataGridTemplateColumn>
    </data:DataGrid.Columns>
</data:DataGrid>

I need to encapsulate this column into a single, reusable control and I want to specify a Binding for it just like for an ordinary DataGridTextColumn. In other words, when using this custom column, I just want to write something like this:

<data:DataGrid>
    <data:DataGrid.Columns>
        <controls:CustomColumn Header="Name" Binding="{Binding Name}" />
    </data:DataGrid.Columns>
</data:DataGrid>

Problem is that the DataGridTemplateColumn my custom column is inheriting from does not have the Binding property. I thought that I will be able to use DataGridBoundColumn, but it's not possible to specify a CellTemplate for it.

How to achieve a desired behavior? Thank you!

2条回答
Emotional °昔
2楼-- · 2020-03-04 05:46

The question is pretty old, but i recently faced this issue myself. An Alternative to @Gregfr answer above is to write your custom DataGridColumn class. The following is what i have done for DatePicker Column:

 public class DataGridDatePickerColumn : DataGridBoundColumn
  {
    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
    {
      var datePicker = new DatePicker();
      datePicker.SetBinding(DatePicker.TextProperty, this.Binding);
      datePicker.SetBinding(DatePicker.SelectedDateProperty, this.Binding);
      return datePicker;
    }

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
      var textBlock = new TextBlock();
      textBlock.SetBinding(TextBlock.TextProperty, this.Binding);
      return textBlock;
    }
  }

Then i use it in one-line call in my xaml-pages like this:

<h:DataGridDatePickerColumn IsReadOnly="False" Header="Some Date" Binding="{Binding SomeDate, StringFormat='dd.MM.yyyy'}" />

In your case you could extend this C# Class by writing supporting functions that work with PreviewTextInput property and use regex expressions like [0-9]+ to control editing.

查看更多
Root(大扎)
3楼-- · 2020-03-04 05:48

I think the simplest thing to do is to create a customcontrol then use it like this:

            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <controls:CustomColumn Header="Name" Binding="{Binding Name}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

I did something similar yesterday, and it works pretty well

查看更多
登录 后发表回答