为什么我的触发器最终会出现空白控件?

Bra*_*NET 6 c# wpf xaml

在WPF中,我试图创建一个"标志"控件,根据绑定的依赖属性显示复选标记或X(Flag)

<UserControl x:Name="Root" (Other user control stuff)>
     <ContentControl Height="20" x:Name="flagHolder">
            <ContentControl.Style>
                <Style TargetType="ContentControl">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=Root, Path=Flag}" Value="False">
                            <Setter Property="Content" Value="{StaticResource XIcon}" />
                            <Setter Property="Foreground" Value="Crimson"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding ElementName=Root, Path=Flag}" Value="True">
                            <Setter Property="Content"  Value="{StaticResource CheckIcon}" />
                            <Setter Property="Foreground" Value="ForestGreen"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>     
</UserControl>
Run Code Online (Sandbox Code Playgroud)

启动时,每个图标都是正确的(我有几个控件,每个控件都绑定到不同的值).然而,当我切换一些(一个"关闭"转为"打开"而一个当前"打开"转为"关闭")时,我看到两件事:

  1. "打开"的控件已成为绿色检查(根据需要)
  2. "关闭"的控件现在只是空白

检查可视化树似乎表明一切正常(虽然我可能很容易在这里遗漏一些东西),并且触发器的顺序似乎并不重要.我究竟做错了什么?

这是一个示例图标,路径几何体因为它只是噪声而被删除:

<Viewbox x:Key="CheckIcon" x:Shared="False">
    <Path Style="{StaticResource IconPathStyle}">
        <Path.Data>
            <PathGeometry Figures="Bunch of SVG" FillRule="NonZero"/>
        </Path.Data>
    </Path>
</Viewbox>
Run Code Online (Sandbox Code Playgroud)

361*_*615 1

我无法重现您的问题,但这是我所拥有的并且它正在工作:

应用程序.xaml

<Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
  <Application.Resources>
    <Viewbox  x:Key="CheckIcon" x:Shared="False">
      <Canvas Height="24" Width="32">
        <Path Width="7.85446" Height="8.57578" Canvas.Left="-0.0522281" Canvas.Top="-0.100391" Stretch="Fill" StrokeThickness="1.04192" StrokeMiterLimit="2.75" Stroke="#FF000000" Data="F1 M 0.468732,4.66838L 3.03345,7.95443L 7.28127,0.420569"/>
      </Canvas>
    </Viewbox>

      <Viewbox  x:Key="XIcon" x:Shared="False">
      <Canvas Height="24" Width="32">
        <Path Data="M0,0 L1,1 M0,1 L1,0" Stretch="Fill" Stroke="Black" StrokeThickness="3" Width="12" Height="12" />
       </Canvas>
      </Viewbox>
  </Application.Resources>
</Application>
Run Code Online (Sandbox Code Playgroud)

是否.xaml

<UserControl x:Class="WpfApplication1.YesNo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Name="Root">

  <ContentControl Height="20" Name="flagHolder">
    <ContentControl.Style>
      <Style TargetType="ContentControl">

        <Style.Triggers>
          <DataTrigger Binding="{Binding ElementName=Root, Path=Flag}" Value="False">
            <Setter Property="Content" Value="{StaticResource XIcon}" />
            <Setter Property="Foreground" Value="Crimson"/>
          </DataTrigger>
          <DataTrigger Binding="{Binding ElementName=Root, Path=Flag}" Value="True">
            <Setter Property="Content"  Value="{StaticResource CheckIcon}" />
            <Setter Property="Foreground" Value="ForestGreen"/>
          </DataTrigger>
        </Style.Triggers>
      </Style>
    </ContentControl.Style>
  </ContentControl>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

YesNo.xaml.cs

using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class YesNo : UserControl
    {
        public YesNo()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty FlagProperty = DependencyProperty.Register(
            "Flag", typeof(bool), typeof(YesNo), new PropertyMetadata(default(bool)));

        public bool Flag {
            get {
                return (bool) GetValue(FlagProperty);
            }
            set {
                SetValue(FlagProperty, value);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

主窗口.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfApplication1="clr-namespace:WpfApplication1"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Title="" Width="400" Height="400">

  <StackPanel Orientation="Vertical" Margin="50">
    <wpfApplication1:YesNo Flag="{Binding Flag1}"/>
    <wpfApplication1:YesNo Flag="{Binding Flag2}"/>
    <wpfApplication1:YesNo Flag="{Binding Flag2}"/>
    <wpfApplication1:YesNo Flag="{Binding Flag1}"/>
    <Button Content="Toggle" Click="ButtonBase_OnClick"></Button>
  </StackPanel>
</Window>
Run Code Online (Sandbox Code Playgroud)

MainWindow.xaml.cs

public partial class MainWindow : INotifyPropertyChanged
{
    private bool _flag1;
    private bool _flag2;

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Flag1 = true;
        Flag2 = false;
    }
    public bool Flag1 {
        get {
            return _flag1;
        }
        set {
            _flag1 = value;
            OnPropertyChanged();
        }
    }

    public bool Flag2 {
        get {
            return _flag2;
        }
        set {
            _flag2 = value;
            OnPropertyChanged();
        }
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e) {
        Flag1 = !Flag1;
        Flag2 = !Flag2;
    }
}
Run Code Online (Sandbox Code Playgroud)

看起来如何:

截屏

视频:http://www.screencast.com/t/J5IY7DR3Ry