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
属性改变?
尝试更新您现有的代码,如下所示:
<DataTrigger Binding="{Binding my:ReportSettingsData.SelectedReport}" Value="{x:Static my:SelectedReportType.DiagSummary}">
<Setter Property="TextBlock.Foreground" Value="{StaticResource BgBrush1}" />
</DataTrigger>
还有什么是你绑定到DataGrid项目源请让我知道。