无法通过 DataTrigger 设置 ContentTemplate

发布于 2024-08-18 11:26:07 字数 2953 浏览 10 评论 0原文

我希望 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

I want the ContentTemplate to vary according to the value in the DataTrigger.
And yes, I considered using a DataTemplateSelector, but now I need a DataTrigger or better said a MultiDataTrigger.

Please take a look at the following sample app, the DataTemplate doesn't change:

<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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

¢好甜 2024-08-25 11:26:07

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

中Xaml的唯一问题是ContentTemplate在ContentControl上明确设置并且不在样式中,这会覆盖触发器。在样式中设置它可以解决问题

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

I know the OP has no use for this answer anymore but I thought I'd answer it anyway in case anyone else comes along with the same problem

The only problem with the Xaml in the question is that the ContentTemplate is set explicilty on the ContentControl and not in the Style and this overrides the Trigger. Setting it in the Style instead fixes the problem

<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>
屋顶上的小猫咪 2024-08-25 11:26:07

以下是对我有用的东西:

<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 进行操作。

Here's something that works for me:

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

Note that my DataTemplate is another ContentControl, which allows my DataTemplate.Triggers to operate on the ContentTemplate of that (nested) ContentControl.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文