c# - 如何访问 DataGrid RowHeaderTemplate 或 DataGrid.RowHeaderSyle 中定义的元素
问题描述
我下面的代码
<DataGrid.RowHeaderTemplate >
<DataTemplate>
<CheckBox x:Name="SelectedItemCheckBox"
Margin="5 0 0 0"
IsChecked="{Binding Path=IsSelected,
Mode=TwoWay,
RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGridRow}}}">
</CheckBox>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
或者
<DataGrid.RowHeaderStyle>
<Style TargetType="{x:Type DataGridRowHeader}">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRowHeader}">
<CheckBox x:Name="SelectedItemCheckBox"
Margin="5 0 0 0"
IsChecked="{Binding Path=IsSelected,
Mode=TwoWay,
RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGridRow}}}">
</CheckBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.RowHeaderStyle>
选择行时,如何从后面的代码访问 SelectedItemCheckBox ?
到目前为止我所拥有的:
private CheckBox GetCheckbox(int index)
{
DataGridRow row = (DataGridRow)MyGrid.ItemContainerGenerator.ContainerFromIndex(index);
//how do I get to that checkbox here ?
}
MyGrid 的 ItemSource 在后面的代码中设置,通常我会通过访问 MyGrid.Columns[] 来访问单元格,但这是一个行标题,它不是 Columns[] 的一部分。
请注意,根据 ItemSource 大小定义了此复选框的许多行。
另外我想知道是否有一种方法可以在不更改 xaml 并按原样使用它的情况下访问复选框。
解决方案
如果您想在代码隐藏中访问行标题的复选框(而不是使用绑定),您可以“遍历”所选 DataGridRow 的可视化树以查找标题。
将 SelectionChanged 事件处理程序添加到 DataGrid:
<DataGrid x:Name="Grid" Loaded="Grid_Loaded" SelectionChanged="Grid_SelectionChanged">
然后在代码隐藏中:
- 获取选中的行
- 使用 VisualTreeHelper 找到标题的复选框
施展你的魔法
private void Grid_SelectionChanged(object sender, SelectionChangedEventArgs e) { var item = (DataGridRow)Grid.ItemContainerGenerator.ContainerFromItem(e.AddedItems[0]); var control = FindChild<CheckBox>(item, "SelectedItemCheckBox"); control.IsChecked = true; }
对于 FindChild,这里有多个可用选项:如何按名称或类型查找 WPF 控件?
我在此示例中使用了以下内容:如何按名称或类型查找 WPF 控件?
public static T FindChild<T>(DependencyObject depObj, string childName)
where T : DependencyObject
{
// Confirm obj is valid.
if (depObj == null) return null;
// success case
if (depObj is T && ((FrameworkElement)depObj).Name == childName)
return depObj as T;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
//DFS
T obj = FindChild<T>(child, childName);
if (obj != null)
return obj;
}
return null;
}
推荐阅读
- flutter - 如何在 Firebase 中使用循环进度指示器
- c# - 如何对没有模型文件夹的控制器执行单元测试
- yii2 - Yii2 - 为什么使用 Pjax 无法正常工作的 Listview 中的 ajax 更改页面
- algorithm - 如何从任务池中排序任务以最小化时间成本?
- c++ - C ++ 20中可变参数函数中的多个概念约束参数包不接受第一个参数包中的参数
- pip - python 3.8.2有ensurepip吗?我需要安装 ensurepip 才能使用它吗?
- c - 有没有办法使用 C 在 Windows 上获取文件的大小?
- typescript - Typescript:为文件中的所有函数声明 ReturnType(如何创建 redux 操作类型)
- javascript - 运行图像组合过滤器引导代码时的 Javascript 问题
- angular - 材料对话框测试数据未进入我的对话框