Reputation: 2588
I'm using WPF's regular DataGrid inside a custom control. One of the DataGrid's cell template content should be bound to a the Text of a Textblock or to a DependencyProperty on the custom control. (If I could bind it to any of them it's good enough for me)
I tried to do the following binding with the ElementName but it didn't work. I keep getting an DependencyProperty.UnsetValue -
<DataGridTemplateColumn Header="Test">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentPresenter>
<ContentPresenter.Content>
<MultiBinding Converter="{StaticResource TextToSpecialTextblockConverter}">
<Binding Path="SomeTextOnTheViewModel"/>
<Binding ElementName="SearchBox" Path="Text" Mode="OneWay"/>
</MultiBinding>
</ContentPresenter.Content>
</ContentPresenter>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Binding to a DependencyProperty also doesn't work.
<DataGridTemplateColumn Header="Test">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentPresenter>
<ContentPresenter.Content>
<MultiBinding Converter="{StaticResource TextToSpecialTextblockConverter}">
<Binding Path="SomeTextOnTheViewModel"/>
<Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="SomeDP" />
</MultiBinding>
</ContentPresenter.Content>
</ContentPresenter>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I hope someone could help me out!
Thanks!
Upvotes: 1
Views: 22129
Reputation: 42991
If the property Property
is defined on a view model set on the DataContext
of the control or DataGrid
then this sample works:
Resources:
<DataTemplate x:Key="template">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Test"/>
<TextBlock Text="{Binding Path=DataContext.Property,RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
</StackPanel>
</DataTemplate>
DataGrid
<DataGrid ItemsSource="{Binding Items}" ...>
<DataGrid.Columns>
<DataGridTemplateColumn CellTemplate="{StaticResource template}" />
The DependencyProperty change notification could update the view model.
For example:
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register("Test", typeof (string), typeof (DataGridComboBoxColumn), new PropertyMetadata(default(string), PropertyChangedCallback));
public string Test
{
get { return (string) GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
((MyControl) dependencyObject).OnTestChanged();
}
private void OnTestChanged()
{
((MyViewModel) theGrid.DataContext).Property = Test;
}
In order to bind to a dependency property Test
using a template binding use this
<DataTemplate x:Key="template2">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Test: "/>
<TextBlock Text="{Binding Path=Test, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:CustomControl1}}}"/>
</StackPanel>
</DataTemplate>
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<DataGrid ItemsSource="{TemplateBinding ItemsSource}" AutoGenerateColumns="True">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Test" CellTemplate="{StaticResource template2}" />
</DataGrid.Columns>
</DataGrid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Where CustomControl1 is
public class CustomControl1 : ItemsControl
{
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof (CustomControl1),
new FrameworkPropertyMetadata(typeof (CustomControl1)));
}
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register("Test", typeof (string), typeof (CustomControl1), new PropertyMetadata(default(string)));
public string Test
{
get { return (string) GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
}
Upvotes: 6