Reputation: 25905
I'm trying to bind a ViewModel property to a Checkbox in the header of a DataGrid.
The checkbox binds just fine if I stick it randomly in the window, but if its in the header of the datagrid, it doesn't bind in either direction.
The data in the DataGrid binds fine as well.
The issue seems to be that the HeaderTemplate isn't binding to the main view model. I assume its binding ItemSource.
How do I bind to the view model in the header?
<DataGrid ItemsSource="{Binding Channels}" AlternationCount="2" Grid.IsSharedSizeScope="True" AutoGenerateColumns="False" AlternatingRowBackground="{StaticResource GroupBackgroundBrush}" SelectedIndex="{Binding Path=CursorChannelInt}" >
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=Test}">Test Chkbox</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=stuff}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Upvotes: 1
Views: 2116
Reputation: 31
The above answers were not working in my case, so I solved using Initialized event trigger
.xaml
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox Initialized="CheckBox_Initialized" IsChecked="False">Test Chkbox</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
.xaml.cs
private CheckBox cb_All = null;
private void CheckBox_Initialized(object sender, EventArgs e)
{
cb_All = (CheckBox)sender;
}
private void Function()
{
if(cb_All != null)
cb_All.IsChecked = true; //or false
}
It is sooo late, spending several years.. but I hope this may help to anyone:)
Upvotes: 1
Reputation: 13679
if the property is not in the collection, you have perhaps a nice answer, other rewrite for the same would be to use the ElementName
to shorten the binding syntax
sample
<DataGrid ItemsSource="{Binding Channels}" AlternationCount="2" Grid.IsSharedSizeScope="True" AutoGenerateColumns="False" AlternatingRowBackground="{StaticResource GroupBackgroundBrush}" SelectedIndex="{Binding Path=CursorChannelInt}"
x:Name="dGrid">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding DataContext.Test, ElementName=dGrid}">Test Chkbox</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=stuff}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
above sample is based on the assumption that the property Test
is in the same VM as Channels
property.
Upvotes: 0
Reputation: 25905
This works, by going to the Window, getting its DataContext, and going from there. Is there a better way?
<CheckBox IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Test}">Test Chkbox</CheckBox>
Upvotes: 1