c# - 为什么我的触发器以空白控件结束?

标签 c# wpf xaml

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

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

启动时每个图标都是正确的(我有几个这样的控件,每个都绑定(bind)到不同的值)。但是,当我切换几个(一个“关闭”变为“打开”,一个当前“打开”变为“关闭”)时,我看到两件事:

  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>

最佳答案

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

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

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

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);
            }
        }
    }
}

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

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

它的样子:

screenshot

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

关于c# - 为什么我的触发器以空白控件结束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40644711/

相关文章:

c# - 事务 Rollback() 是否有机会抛出异常?

c# - zxing条码扫描 fragment

C#/Java 可移植性

c# - 泛型类型转换器 - 泛型问题

WPF 绑定(bind)到代理

c# - WP8 XAML DataTrigger CallMethodAction 用于从代码后面调用方法

c# - Wpf Prism 区域导航

c# - XAML WPF 数据网格 : reduce columns width to fit its content while scrolling except one

c# - ASP.NET MVC 客户端验证消息错误

c# - 通过触发器更改文本 block 中文本的颜色