本文介绍了DataTigger在CellTemplate绑定到HeaderTemplate;它能工作吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里的目标是检查所有网格复选框,如果标题复选框更改:

 < Window.Resources> 

< Style TargetType =CheckBoxx:K​​ey =InnerBox>
< Setter Property =Horizo​​ntalAlignmentValue =Center/>
< Style.Triggers>
< DataTrigger Value =True
Binding ={Binding IsChecked,
ElementName = HeaderCheckbox}>
< Setter Property =IsCheckedValue =True/>
< / DataTrigger>
< DataTrigger Value =False
Binding ={Binding IsChecked,
ElementName = HeaderCheckbox}>
< Setter Property =IsCheckedValue =False/>
< / DataTrigger>
< /Style.Triggers>
< / Style>

< /Window.Resources>

< DataGrid>
< DataGrid.Columns>

<! - col1 - >
< DataGridTemplateColumn>
< DataGridTemplateColumn.HeaderTemplate>
< DataTemplate>
<! - 标题检查 - >
< CheckBox Name =HeaderCheckbox/>
< / DataTemplate>
< /DataGridTemplateColumn.HeaderTemplate>
< DataGridTemplateColumn.CellTemplate>
< DataTemplate>
<! - 身体检查 - >
< CheckBox Style ={StaticResource InnerBox}/>
< / DataTemplate>
< /DataGridTemplateColumn.CellTemplate>
< / DataGridTemplateColumn>

<! - col2 - >
< DataGridTextColumn Binding ={Binding}Header =Text/>
< /DataGrid.Columns>

<! - 样本数据 - >
< sys:String> 1< / sys:String>
< sys:String> 2< / sys:String>
< sys:String> 3< / sys:String>
< / DataGrid>

看起来像:





由于某些原因,触发器不会触发。 / p>

任何想法?

解决方案

ElementName 绑定在一个 DataTemplate 中,不能达到您注意到的模板之外的元素。这是因为它可以被实例化很多次并具有自己的名称,所以任何 ElementName 绑定你在 DataTemplate 在模板中查看另一个具有该名称的元素。



使用Snoop查看它,我们也可以看到, RelativeSource 绑定不能直接使用,因为它们是在Visual Tree的不同部分





我可以想到的唯一的事情是将两个CheckBox绑定到一个共同的祖先,例如父级 DataGrid 并使用附加属性或标签属性。示例

 < Style TargetType =CheckBoxx:K​​ey =InnerBox> 
< Setter Property =Horizo​​ntalAlignmentValue =Center/>
< Setter Property =IsCheckedValue =False/>
< Style.Triggers>
< DataTrigger Value =True
Binding ={Binding RelativeSource = {RelativeSource AncestorType = {x:Type DataGrid}},
Path = Tag}>
< Setter Property =IsCheckedValue =True/>
< / DataTrigger>
< /Style.Triggers>
< / Style>

 < DataTemplate> 
<! - 标题检查 - >
< CheckBox Name =HeaderCheckbox
IsChecked ={Binding RelativeSource = {RelativeSource AncestorType = {x:Type DataGrid}},
Path = Tag,
Mode = OneWayToSource }/>
< / DataTemplate>


The goal here would be to check all grid checkboxes if the header checkbox changes:

<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>

Looks like:

For some reason, the trigger does not fire.

Any ideas?

解决方案

ElementName binding inside a DataTemplate can't reach an element outside of the template as you noticed. This is because it can be instantiated many times and has its own namescope so any ElementName binding you create inside a DataTemplate will look inside the template for another element with that name.

Looking at it with Snoop we can also see that a RelativeSource binding can't be used directly since they are in different parts of the Visual Tree

The only thing that I can think of to get around this is to bind both of the CheckBoxes to a common ancestor, e.g. the parent DataGrid and use an attached property or the Tag property. Example

<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>

and

<DataTemplate>
    <!-- header check -->
    <CheckBox Name="HeaderCheckbox"
              IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
                                  Path=Tag,
                                  Mode=OneWayToSource}"/>
</DataTemplate>

这篇关于DataTigger在CellTemplate绑定到HeaderTemplate;它能工作吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 11:26