无法通过 DataTrigger 设置 ContentTemplate

Posted

技术标签:

【中文标题】无法通过 DataTrigger 设置 ContentTemplate【英文标题】:Unable to set ContentTemplate via DataTrigger 【发布时间】:2011-01-06 14:29:23 【问题描述】:

我希望ContentTemplate 根据DataTrigger 中的值而变化。 是的,我考虑过使用DataTemplateSelector,但现在我需要DataTrigger,或者更好的是MultiDataTrigger

请查看以下示例应用程序,DataTemplate 不会改变:

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:WpfApplication1">
    <StackPanel>
        <CheckBox IsChecked="Binding BoolProperty, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type src:Window1" Content="BoolProperty"/>
        <ContentControl Content="Binding BoolProperty, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type src:Window1">
            <ContentControl.ContentTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="Binding BoolProperty, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type src:Window1" Content="Template 1"/>
                </DataTemplate>
            </ContentControl.ContentTemplate>
            <ContentControl.Resources>
                <DataTemplate x:Key="Template2">
                    <CheckBox IsChecked="Binding BoolProperty, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type src:Window1" Content="Template 2"/>
                </DataTemplate>
            </ContentControl.Resources>
            <ContentControl.Style>
                <Style TargetType="ContentControl">
                    <Style.Triggers>
                        <DataTrigger Binding="Binding BoolProperty, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type src:Window1" Value="True">
                            <Setter Property="ContentTemplate" Value="StaticResource Template2"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
        <Button Name="btnSwitch" Content="Switch"/>
    </StackPanel>
</Window>

Partial Class Window1
    Public Property BoolProperty() As Boolean
        Get
            Return GetValue(BoolPropertyProperty)
        End Get
        Set(ByVal value As Boolean)
            SetValue(BoolPropertyProperty, value)
        End Set
    End Property
    Public Shared ReadOnly BoolPropertyProperty As DependencyProperty = DependencyProperty.Register("BoolProperty", GetType(Boolean), GetType(Window1), New FrameworkPropertyMetadata(False))

    Private Sub btnSwitch_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnSwitch.Click
        BoolProperty = Not BoolProperty
    End Sub
End Class

【问题讨论】:

【参考方案1】:

我知道 OP 不再需要这个答案,但我想无论如何我都会回答它,以防其他人遇到同样的问题

问题中 Xaml 的唯一问题是 ContentTemplate 设置在 ContentControl 上而不是 Style 上,这会覆盖触发器。将其设置在 Style 中可以解决问题

<ContentControl Content="Binding BoolProperty, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type src:Window1">
    <ContentControl.Resources>
        <DataTemplate x:Key="Template2">
            <CheckBox IsChecked="Binding BoolProperty, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type src:Window1" Content="Template 2"/>
        </DataTemplate>
    </ContentControl.Resources>
    <ContentControl.Style>
        <Style TargetType="ContentControl">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <CheckBox IsChecked="Binding BoolProperty, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type src:Window1" Content="Template 1"/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <DataTrigger Binding="Binding BoolProperty, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type src:Window1" Value="True">
                    <Setter Property="ContentTemplate" Value="StaticResource Template2"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

【讨论】:

【参考方案2】:

这里有一些对我有用的东西:

<ContentControl Content="Binding SomeBool">
  <ContentControl.Resources>
    <DataTemplate x:Key="PinkTemplate">
      <TextBlock Text="Binding" Background="Pink" />
    </DataTemplate>
    <DataTemplate x:Key="LimeTemplate">
      <TextBlock Text="Binding" Background="Lime" />
    </DataTemplate>
  </ContentControl.Resources>
  <ContentControl.ContentTemplate>
    <DataTemplate>
      <ContentControl Name="cc"
                      Content="Binding"
                      ContentTemplate="StaticResource PinkTemplate" />
      <DataTemplate.Triggers>
        <DataTrigger Binding="Binding" Value="True">
          <Setter TargetName="cc" 
                  Property="ContentTemplate"
                  Value="StaticResource LimeTemplate" />
        </DataTrigger>
      </DataTemplate.Triggers>
    </DataTemplate>
  </ContentControl.ContentTemplate>
</ContentControl>

请注意,我的 DataTemplate 是另一个 ContentControl,它允许我的 DataTemplate.Triggers 对那个(嵌套的)ContentControl 的 ContentTemplate 进行操作。

【讨论】:

如果有帮助:除非将 StaticResource 更改为 DynamicResource,否则您可能会遇到异常。

以上是关于无法通过 DataTrigger 设置 ContentTemplate的主要内容,如果未能解决你的问题,请参考以下文章

消除重复的 DataTrigger 逻辑

WPF DataTrigger 动画只触发一次

WPF DataGrid - 如何设置正确的 DataTrigger 绑定到单元格的数据源(而不是行的源)

WPF ItemsControl DataTrigger EnterActions动画未启动

绑定属性上的 DataTrigger

WPF Datatrigger ColorAnimation 不起作用