Reputation: 231
I spent the past one hour trying to figure this out. I have a CheckBox
inside DataGrid
as follows:
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<CheckBox Name="chkall" Content="Select All" Checked="chkall_Checked" Unchecked="chkall_Unchecked"/>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Tag="{Binding Path=id}" x:Name="chksingle" Checked="chksingle_Checked" Unchecked="chksingle_Unchecked"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
As you can see I am trying to check and uncheck the CheckBox
es inside DataGrid
rows when the CheckBox
in the header is checked or unchecked. This is the code where I am trying to retrieve the CheckBox
and mark it as checked:
private void chkall_Checked(object sender, RoutedEventArgs e)
{
foreach (var r in userDG.Items)
{
DataGridRow row =(DataGridRow)userDG.ItemContainerGenerator.ContainerFromItem(r);
FrameworkElement FW_element = userDG.Columns[0].GetCellContent(row);
FW_element.ApplyTemplate();
var checkbox = FW_element.FindName("chksingle") as CheckBox;
checkbox.IsChecked = false;
}
}
I have already tried RegisterName()
method and I've tried VisualTreeHelper
but nothing works.
This line always returns null
:
var checkbox = FW_element.FindName("chksingle") as CheckBox;
Here is a WPF visualizer screenshot for my FrameworkElement
where I can clearly see the checkbox I am trying to find:
Please tell me what am I doing wrong? Thank you.
Upvotes: 0
Views: 3295
Reputation: 10349
The thing is that a DataTemplate
is a name scope boundary, that is the templated element (a ContentPresenter
in this case) or any of it's ancestors are not aware of named elements defined inside the template. In order to find a named element inside the template you need to use the DataTemplate.FindName
method instead (inherited from FrameworkTemplate
). Notice that it takes two parameters instead of one, the second one being the templated element. This should do the trick for you:
private void chkall_Checked(object sender, RoutedEventArgs e)
{
foreach (var r in userDG.Items)
{
DataGridRow row = (DataGridRow)userDG.ItemContainerGenerator.ContainerFromItem(r);
FrameworkElement FW_element = userDG.Columns[0].GetCellContent(row);
//We use the CellTemplate defined on the column to find the CheckBox
var checkbox = ((DataGridTemplateColumn)userDG.Columns[0]).CellTemplate.FindName("chksingle", FW_element) as CheckBox;
checkbox.IsChecked = true;
}
}
Upvotes: 3
Reputation: 169360
Try this:
FrameworkElement FW_element = userDG.Columns[0].GetCellContent(row);
CheckBox checkbox = VisualTreeHelper.GetChild(FW_element, 0) as CheckBox;
Upvotes: 0
Reputation: 516
The CheckBox does not exist in the scope that the Row knows. It is not a Direct child of its Template.
You need to use the static class VisualTreeHelper to drill down from the row to find an instance of type CheckBox, and compare against its x:Name.
Upvotes: 0