DataTrigger в привязке CellTemplate к HeaderTemplate;это может работать? - PullRequest
2 голосов
/ 30 августа 2011

Цель здесь состоит в том, чтобы проверить все флажки сетки, если флажок заголовка изменится:

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

Похоже:

Screen

По некоторым причинам,курок не срабатывает.

Есть идеи?

Ответы [ 2 ]

4 голосов
/ 30 августа 2011

ElementName привязка внутри DataTemplate не может достичь элемента за пределами шаблона, как вы заметили. Это связано с тем, что его можно создавать многократно и иметь собственную область имен, поэтому любая привязка ElementName, созданная вами внутри DataTemplate, будет искать внутри шаблона другой элемент с таким именем.

Глядя на это с помощью Snoop, мы также видим, что привязка RelativeSource не может использоваться напрямую, поскольку они находятся в разных частях дерева визуалов

enter image description here

Единственное, что я могу придумать, чтобы обойти это, - это связать оба 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>
0 голосов
/ 30 августа 2011

Я не думаю, что регулярная привязка данных к HeaderCheckBox возможна, поскольку CheckBox существует как часть Template и находится в другой ветви VisualTree, чем DataGridItems* 1006.*

Обычно я делаю все наоборот: когда проверяется заголовок CheckBox, проверьте всю строку CheckBoxes.Моя основная причина этого заключается в том, что флажки обычно присутствуют, поэтому пользователи могут их отмечать / снимать, и если они связаны с состоянием проверки CheckBox заголовка, то пользователь не может их изменять.

Для реализациито есть я обычно подключаюсь к событию Click или Checked контрольного блока заголовка.

Если состояние строки CheckBox.IsChecked связано с чем-то в ViewModel, я подключу событие к Command в моей ViewModel и установите элемент данных, с которым CheckBox.IsChecked связан true / false, в зависимости от состояния CheckBox заголовка (обычно передается как CommandParameter)

Еслисостояние CheckBox.IsChecked ни к чему не привязано, вы можете использовать обычный code-behind для циклического просмотра вашего DataGrid.Items, использовать ItemContainerGenerator, чтобы получить ItemContainer для каждого элемента, найти CheckBox, а затем установить его проверкусостояние.

...