WPF & XAML newbie here, so it's likely I have a totally wrong concept of how Triggers work...
Based on this question, I got my Trigger to work, but it runs only once on initial display of the screen, and takes whatever the initial value of the property is. If the property later changes (which can occur only when that screen is closed), when I re-open that screen, the Trigger behaves as if the property hadn't changed (i.e. it uses the property's original value).
What may be complicating the issue (maybe?) is that the class that defines the Trigger's DependencyProperty is a singleton. It was a singleton before I ever touched the code; I just added the DependencyProperty so I could add a Style Trigger in the XAML code to get different behavior depending on the selected report type. In the C# class property getter/setter I had to add the ".Instance
" to access GetValue() and SetValue(), since the class is a singleton and I made the C# property a static. Not sure if that would mess up the DependencyProperty scheme, but I know that there's only one ReportSettingsData object being created because the Exception in the constructor is never thrown.
Here's a portion of the singleton class:
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));
); } }
And the XAML for the reports page:
<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>
The default value of the SelectedReport
property is set in the last line of the C# code above. If I set the default to DiagSummary
, the Trigger in the XAML code fires and I get Goldenrod
text for all four report types, regardless of the actual value of the SelectedReport
property at the point I display the report screen. However, if I change the default to EquipSummary
(or any other report type), that gives me HotPink
text for all four report types. How can I get the Style Trigger & Setter to re-run if the SelectedReport
property changes?