0

I want my datagrid columns to share a cell/celledit template.

I have the solution do that (thanks to WPF DataGridTemplateColumn shared template?). Now what I would love to is improving the readability by avoiding all the node nesting.

My current view looks like that:

  <wpftk:DataGrid ItemsSource="{Binding Tests}" AutoGenerateColumns="False">

    <wpftk:DataGrid.Resources>
      <DataTemplate x:Key="CustomCellTemplate">
        <TextBlock Text="{TemplateBinding Content}"/>
      </DataTemplate>
      <DataTemplate x:Key="CustomCellEditingTemplate">
        <TextBox Text="{TemplateBinding Content}"></TextBox>
      </DataTemplate>
    </wpftk:DataGrid.Resources>

    <wpftk:DataGrid.Columns>

      <wpftk:DataGridTemplateColumn Header="Start Date">
        <wpftk:DataGridTemplateColumn.CellTemplate>
          <DataTemplate>
            <ContentPresenter ContentTemplate="{StaticResource CustomCellTemplate}" Content="{Binding StartDate}"/>
          </DataTemplate>
        </wpftk:DataGridTemplateColumn.CellTemplate>
        <wpftk:DataGridTemplateColumn.CellEditingTemplate>
          <DataTemplate>
            <ContentPresenter ContentTemplate="{StaticResource CustomCellEditingTemplate}" Content="{Binding StartDate}"/>
          </DataTemplate>
        </wpftk:DataGridTemplateColumn.CellEditingTemplate>
      </wpftk:DataGridTemplateColumn>

      <!--and again the whole block above for each columns...-->

    </wpftk:DataGrid.Columns>
  </wpftk:DataGrid>

What I would like to achieve is to bind the value at the DataGridTemplateColumn level and propagate it to the template level. Anyone know how to do that?

What I tried to do is something like that:

  <wpftk:DataGrid ItemsSource="{Binding Tests}" AutoGenerateColumns="False">

    <wpftk:DataGrid.Resources>
      <DataTemplate x:Key="CustomCellTemplate">
        <TextBlock Text="{Binding}"/>
      </DataTemplate>
      <DataTemplate x:Key="CustomCellEditingTemplate">
        <TextBox Text="{Binding}"></TextBox>
      </DataTemplate>
    </wpftk:DataGrid.Resources>

    <wpftk:DataGrid.Columns>
      <wpftk:DataGridTemplateColumn Header="Start Date" Binding="{Binding StartDate}" CellTemplate="{StaticResource CustomCellTemplate}" CellEditingTemplate="{StaticResource CustomCellEditingTemplate}"/>
      <wpftk:DataGridTemplateColumn Header="End Date" Binding="{Binding EndDate}" CellTemplate="{StaticResource CustomCellTemplate}" CellEditingTemplate="{StaticResource CustomCellEditingTemplate}"/>
    </wpftk:DataGrid.Columns>
  </wpftk:DataGrid>

Obviously the binding porperty is not a valid property of the DataGridTemplateColumn but maybe by playing with the datacontext and some relative source could do the trick but frankly I can't find a way to implement that.

Not sure if what I want is possible and i'm willing to accept a "no way you can do that" as an answer

NOTE: The TextBlock/TextBox in the template is just for test (the real template is much more complex) DataGridTextColumn will not do the trick Thanks in advance

Community
  • 1
  • 1
Guillaume
  • 1,176
  • 2
  • 11
  • 27

1 Answers1

1

What you tried should have worked as you reduced the XAML by specifying the DataTemplates using the property syntax.

Edit: Sorry. I misinterpreted your question. To add a bindable property to DataGridTemplateColumn without modifying or access to the source code you can create an AttachedProperty.

Example:

public class DataBindingHelper 
{

    #region AttachedBinding

    public static readonly DependencyProperty AttachedBindingProperty = DependencyProperty.RegisterAttached("AttachedBinding", typeof(Binding), typeof(DataBindingHelper), new FrameworkPropertyMetadata(null));

    public static Binding GetUseAncestorDataContext(DependencyObject d)
    {
        return (bool)d.GetValue(AttachedBindingProperty);
    }

    public static void SetUseAncestorDataContext(DependencyObject d, Binding value)
    {
        d.SetValue(AttachedBindingProperty, value);
    }

    #endregion

}

Usage:

<wpftk:DataGrid ItemsSource="{Binding Tests}" AutoGenerateColumns="False">

    <wpftk:DataGrid.Resources>
        <DataTemplate x:Key="NameTemplate">
            <TextBlock Text="{Binding}"/>
        </DataTemplate> 
        <DataTemplate x:Key="EditingTemplate">
            <TextBox Text="{Binding}"/>
        </DataTemplate>

        <DataTemplate x:Key="CustomCellTemplate">
            <ContentPresenter ContentTemplate="{StaticResource NameTemplate}" 
                              Content="{Binding Path=(helpers:DataBindingHelper.AttachedBinding), RelativeSource={RelativeSource AncestorType={x:Type wpftk:DataGridTemplateColumn}}}" />
        </DataTemplate>
        <DataTemplate x:Key="CustomCellEditingTemplate">
            <ContentPresenter ContentTemplate="{StaticResource EditingTemplate}"
                              Content="{Binding Path=(helpers:DataBindingHelper.AttachedBinding), RelativeSource={RelativeSource AncestorType={x:Type wpftk:DataGridTemplateColumn}}}" />                            
        </DataTemplate>

    </wpftk:DataGrid.Resources>

    <wpftk:DataGrid.Columns>
        <wpftk:DataGridTemplateColumn Header="Start Date" helpers:DataBindingHelper.AttachedBinding="{Binding Path=StartDate}" CellTemplate="{StaticResource CustomCellTemplate}" CellEditingTemplate="{StaticResource CustomCellEditingTemplate}"/>
        <wpftk:DataGridTemplateColumn Header="End Date" helpers:DataBindingHelper.AttachedBinding="{Binding Path=EndDate}" CellTemplate="{StaticResource CustomCellTemplate}" CellEditingTemplate="{StaticResource CustomCellEditingTemplate}"/>
    </wpftk:DataGrid.Columns>

</wpftk:DataGrid>

To learn more about Attached Properties: read the MSDN documentation or any WPF/C# book. They are one of the most powerful things about the data binding system in WPF.


Also if you want to know more about debugging and iterating a WPF application read my recent answer on the topic. Snoop especially would have been helpful for you understand what was going wrong with the above.

Community
  • 1
  • 1
Dennis
  • 20,275
  • 4
  • 64
  • 80
  • Not sure I'm following you, my problem is that I don't know how to bind the actual data directly from the DataGridTemplateColumn, Binding is not a property of the DataGridTemplateColumn. I can bind the edit template and normal template but i don't know how to bind the data to the template. my guess is to set the DataContext of the template with the data I want but I don't know how to do that – Guillaume Mar 23 '12 at 10:12
  • Edited answer to better answer your original question. – Dennis Mar 23 '12 at 11:45
  • Great! that what I was looking for – Guillaume Mar 23 '12 at 11:56
  • Do note that this approach does not work with the built-in DataGrid grid from WPF. – Anton Curmanschii Oct 10 '22 at 11:57