Can a DataTemplate be reused by binding it to different properties with the same data type?

70 Views Asked by At

I use a DataGrid with several columns of the same data type. I want to use a DataGridTemplateColumn for the columns and define a DataTemplate for the CellTemplate and one for the CellEditingTemplate.

Is it possible to bind the text of the DataTemplates to the respective source property?

ViewModel:

class Item : Notifier 
{
    private String name;
    public String Name 
    {
        get { return this.name; }
        set
        {
            this.name = value;
            OnPropertyChanged("Name");
        }
    }

    private String comment = String.Empty;
    public String Comment 
    {
        get { return this.comment; }
                
        set
        {
            this.comment = value;
            OnPropertyChanged("Comment");
        }
    }
}

class MainWindowsViewModel : Notifier
{
    private List<Item> data = new List<Item>();
    public List<Item> Data { get { return this.data; } }

View:

 <Window.Resources>
    <viewmodel:MainWindowsViewModel x:Key="vm"/>

    <!-- readonly template -->
    <DataTemplate x:Key="dt">
        <TextBlock Background="AliceBlue" Margin="5"
            Text="{Binding ???}"/>
    </DataTemplate>
        
    <!-- editing template -->
    <DataTemplate x:Key="edt">
        <TextBox Background="LightCoral" Margin="10"
            Text="{Binding ???}"/>
    </DataTemplate>
</Window.Resources>
    
<Grid>
    <DataGrid 
      DataContext="{StaticResource vm}"
      ItemsSource="{Binding Data}"
      HorizontalAlignment="Left" 
      Margin="10,10,10,10" 
      VerticalAlignment="Top" 
      >
      <DataGrid.Columns>
            <DataGridTemplateColumn
                Header="Name"
                CellTemplate="{StaticResource dt}"
                CellEditingTemplate="{StaticResource edt}"
            />

            <DataGridTemplateColumn
              Header="Comment"
              CellTemplate="{StaticResource dt}"
              CellEditingTemplate="{StaticResource edt}"
            />
        </DataGrid.Columns>
    </DataGrid>
</Grid>
1

There are 1 best solutions below

12
BionicCode On

The DataContext of the DataTemplate is always an instance of the templated data type.

It really helps to set the DataTemplate.DataType property as this will enable code suggestions by the designer.

In your case, the DataContext of the templates is an Item instance:

<Window.Resources>

  <!-- readonly template -->
  <DataTemplate x:Key="dt" 
                DataType="Item">
    <StackPanel>
      <TextBlock Text="{Binding Name}" />
      <TextBlock Text="{Binding Comment}" />
    </DataTemplate>
</Window.Resources>

And avoid string literals whenever possible:

OnPropertyChanged("Comment");

should become

OnPropertyChanged(nameof(this.Comment));