Reputation: 1244
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
Upvotes: 0
Views: 3079
Reputation: 20571
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.
Upvotes: 1