此处的目标是在标题复选框更改时检查所有网格复选框:
<Window.Resources>
<Style TargetType="CheckBox" x:Key="InnerBox">
<Setter Property="HorizontalAlignment" Value="Center" />
<Style.Triggers>
<DataTrigger Value="True"
Binding="{Binding IsChecked,
ElementName=HeaderCheckbox}">
<Setter Property="IsChecked" Value="True" />
</DataTrigger>
<DataTrigger Value="False"
Binding="{Binding IsChecked,
ElementName=HeaderCheckbox}">
<Setter Property="IsChecked" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<DataGrid>
<DataGrid.Columns>
<!-- col1 -->
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<!-- header check -->
<CheckBox Name="HeaderCheckbox" />
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<!-- body check -->
<CheckBox Style="{StaticResource InnerBox}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!-- col2 -->
<DataGridTextColumn Binding="{Binding}" Header="Text" />
</DataGrid.Columns>
<!-- sample data -->
<sys:String>1</sys:String>
<sys:String>2</sys:String>
<sys:String>3</sys:String>
</DataGrid>
看起来像:
由于某种原因,触发器不会触发。
有什么想法吗?
答案 0 :(得分:4)
ElementName
内{p> DataTemplate
绑定无法到达模板外的元素。这是因为它可以多次实例化并具有自己的名称范围,因此您在ElementName
内创建的任何DataTemplate
绑定都将在模板内部查找具有该名称的另一个元素。
使用Snoop查看它我们也可以看到RelativeSource
绑定不能直接使用,因为它们位于Visual Tree的不同部分
我能想到的唯一能解决这个问题的方法是将两个CheckBox绑定到一个共同的祖先,例如:父DataGrid
并使用附加属性或Tag
属性。实施例
<Style TargetType="CheckBox" x:Key="InnerBox">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="IsChecked" Value="False" />
<Style.Triggers>
<DataTrigger Value="True"
Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=Tag}">
<Setter Property="IsChecked" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
和
<DataTemplate>
<!-- header check -->
<CheckBox Name="HeaderCheckbox"
IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=Tag,
Mode=OneWayToSource}"/>
</DataTemplate>
答案 1 :(得分:0)
我认为HeaderCheckBox
的常规DataBinding不可能,因为CheckBox
作为Template
的一部分存在,并且它位于VisualTree
的不同分支中比DataGridItems
通常我反过来说:当检查标题CheckBox
时,检查所有行CheckBoxes
。我的主要原因是因为CheckBoxes通常在那里,所以用户可以检查/取消选中它们,如果它们被绑定到CheckBox选中状态,那么用户就无法改变它们。
为了实现这一点,我通常会挂钩Header CheckBox的Click
或Checked
事件。
如果行CheckBox.IsChecked
状态绑定到ViewModel中的某些内容,我会将事件挂钩到ViewModel中的Command
,并设置CheckBox.IsChecked
为true
的数据项绑定到false
/ CommandParameter
,具体取决于标题CheckBox状态(通常作为CheckBox.IsChecked
传入)
如果DataGrid.Items
状态没有绑定任何内容,您可以使用常规代码隐藏循环遍历ItemContainerGenerator
,使用CheckBox
获取每个项目的ItemContainer,查找{{1}},然后设置它的检查状态。