WPF:如何使触发器在其属性值发生变化时再次触发

本文关键字:变化 属性 何使 触发器 WPF | 更新日期: 2023-09-27 18:05:17

WPF &这里是XAML新手,所以很可能我对触发器的工作方式有一个完全错误的概念…

基于这个问题,我让我的触发器工作,但它只在屏幕的初始显示上运行一次,并接受属性的初始值。如果属性后来发生了变化(只有在屏幕关闭时才会发生),当我重新打开该屏幕时,Trigger的行为就像属性没有改变一样(也就是说,它使用属性的原始值)。

可能使问题复杂化的是(也许?)定义触发器的DependencyProperty的类是单例的。在我接触代码之前,它是一个单例;我只是添加了DependencyProperty,这样我就可以在XAML代码中添加样式触发器,以根据所选的报表类型获得不同的行为。在c#类属性getter/setter中,我必须添加".Instance"来访问GetValue()和SetValue(),因为该类是单例的,并且我将c#属性设置为静态。不确定这是否会弄乱DependencyProperty方案,但我知道只有一个ReportSettingsData对象被创建,因为构造函数中的Exception从未被抛出。

这是单例类的一部分:

namespace MyApplication
{
   public enum SelectedReportType
   {
      EquipSummary,
      EventSummary,
      UserSummary,
      DiagSummary
   }
   public sealed class ReportSettingsData : DependencyObject
   {
      private static ReportSettingsData _instance; // singleton
      static ReportSettingsData() { new ReportSettingsData(); }
      private ReportSettingsData() // private because it's a singleton
      {
         // This is a singleton; the constructor should be called only once. Set _instance here so that
         // it's available immediately in case the constructor needs to access any DependencyProperty's.
         if (_instance != null)
            throw new Exception("ReportSettingsData ctor was called twice.");
         _instance = this;
         // ...other unrelated constructor code...
      }
      public static ReportSettingsData Instance
      {
         get { return _instance; }
      }
      public static SelectedReportType SelectedReport
      {
         get { return (SelectedReportType)Instance.GetValue(SelectedReportProperty); }
         set { Instance.SetValue(SelectedReportProperty, value); }
      }
      public static readonly DependencyProperty SelectedReportProperty =
         DependencyProperty.Register("SelectedReport", typeof(SelectedReportType),
                     typeof(ReportSettingsData)
                     // Set the default state of the 'SelectedReport' property
                     new PropertyMetadata(SelectedReportType.DiagSummary));

);}}

和报告页面的XAML:

<my:HeaderVisual x:Class="MyApplication.ReportsView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:my="clr-namespace:MyApplication">
   <DataGrid Name="_dgReport"
                ColumnWidth="Auto"
                CanUserAddRows="False"
                VerticalScrollBarVisibility="Auto"
                HorizontalScrollBarVisibility="Auto"
                ItemsSource="{Binding}"
                IsReadOnly="True">
      <DataGrid.Resources>
         <Style TargetType="DataGridCell">

            <!-- Default setters for ALL report types... -->
            <Setter Property="TextBlock.Foreground" Value="HotPink"></Setter>

            <!-- But override some settings for Diagnostics reports... -->
            <Style.Triggers>
               <Trigger Property="my:ReportSettingsData.SelectedReport"  Value="{x:Static my:SelectedReportType.DiagSummary}">
                  <Setter Property="TextBlock.Foreground" Value="Goldenrod"></Setter>
               </Trigger>
            </Style.Triggers>

         </Style>
      </DataGrid.Resources>
   </DataGrid>
</my:HeaderVisual>

SelectedReport属性的默认值是在上面c#代码的最后一行设置的。如果我将默认值设置为DiagSummary,则XAML代码中的Trigger将触发,并且无论在显示报告屏幕时SelectedReport属性的实际值如何,我都将获得所有四种报告类型Goldenrod文本。但是,如果我将默认值更改为EquipSummary(或任何其他报表类型),那么将为所有四种报表类型提供HotPink文本。我怎样才能得到样式触发器&设置程序重新运行,如果SelectedReport属性改变?

WPF:如何使触发器在其属性值发生变化时再次触发

尝试更新您现有的代码,如下所示:

        <DataTrigger Binding="{Binding my:ReportSettingsData.SelectedReport}" Value="{x:Static my:SelectedReportType.DiagSummary}">
            <Setter Property="TextBlock.Foreground" Value="{StaticResource BgBrush1}" />
        </DataTrigger>

还有什么是你绑定到DataGrid项目源请让我知道。