无法使用 StaticResource 找到页面共享 DataTrigger 样式转换器

Page shared DataTrigger style converter cannot be found with StaticResource

我正在尝试在空闲时间学习一些 WPF,并且我已经启动了一个应用程序 运行,但是我有一段时间没有想到的事情之一是如何设置样式对于可以出现在页面上的多个数据网格,基于它们将共享的列的行值。

目的是我可以根据货币金额是正数还是负数来设置整行文本颜色的样式 (Foreground 属性)。

到目前为止,我能够得到的结果适用于一对硬编码值,我遇到的问题是连接到一个转换器,它将进行我想要的比较,以便 return True/False...

这是我目前所拥有的:

<DataGrid AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Width="*" Binding="{Binding Date}" Header="Date"/>
        <DataGridTextColumn Width="*" Binding="{Binding Category}" Header="Category"/>
        <DataGridTextColumn Width="*" Binding="{Binding Amount}" Header="Amount"/>
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

我正在尝试设置的特定 Page 将在 3 次不同的时间使用相同类型的网格,数据排列不同。网格本身都按预期工作。

数据网格填充了这个 class:

的集合
public class TransactionDto
{
    public long Id { get; set; }
    public decimal Amount { get; set; }
    public string Category { get; set; }
    public DateTime Date { get; set; }
}

我设置的转换器如下:

public class AmountConverter : IValueConverter
{
    private const decimal Threshold = 0.00m;
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (decimal)value >= Threshold;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

但是,我似乎无法弄清楚数据网格的列与此转换器之间的绑定。这是我到目前为止所尝试的,基于对其他 SO 问题和其他地方发布的答案的试验,但这些情况并不完全相同,并且尝试将其应用于我的情况还没有奏效 - 我得到一个例外,因为到此处的转换器绑定:

<Page.Resources>
<Style TargetType="DataGridRow">
    <Style.Triggers >
        <DataTrigger Binding="{Binding Amount, RelativeSource={RelativeSource Self}, Converter={StaticResource ResourceKey=AmountConverter}}" Value="False">
            <Setter Property="Foreground" Value="Red"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Amount}" Value="-24.71">
            <Setter Property="Foreground" Value="Green"/>
        </DataTrigger>
    </Style.Triggers>
</Style>        

使用 -24.71 硬编码值的触发器工作正常,对于正值的类似触发器也是如此。

代码隐藏 C# 文件包含 属性 所需的转换器类型:

public AmountConverter AmountConverter { get; set; } = new AmountConverter();

我得到的当前异常如下:

System.Windows.Markup.XamlParseException

Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception.

我不太明白这个异常,我不太确定如何继续或它告诉我的是什么问题。

理想情况下,我会在 App.xaml 中设置此样式内容,并从与其相关的数据网格中引用它。

我通过 this article 找到了这个问题的答案。我所做的更改是将以下内容添加到我的 App.xaml 文件中,然后将整个应用程序中所需的更改应用到所有相关的数据网格:

<Application.Resources>
    <local:AmountConverter x:Key="AmountConverter"/>
    <Style TargetType="DataGridRow">
    <Style.Triggers >
        <DataTrigger Binding="{Binding Amount, Converter={StaticResource AmountConverter}}" Value="False">
            <Setter Property="Foreground" Value="Red"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Amount, Converter={StaticResource AmountConverter}}" Value="True">
            <Setter Property="Foreground" Value="Green"/>
        </DataTrigger>
    </Style.Triggers>
    </Style>
</Application.Resources>

在我看来,您的方法有点复杂,使用 2 个触发器来生成绿色或读取。您的转换器也可以 return 颜色,您不需要触发器。

class AmountConverter: IValueConverter {
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
    if (value is int) {
      int quantity = (int)value;
      if (quantity>=100) return Brushes.White;
      if (quantity>=10) return Brushes.WhiteSmoke;
      if (quantity>=0) return Brushes.LightGray;
      return Brushes.White; //quantity should not be below 0
    }
    //value is not an integer. Do not throw an exception
    // in the converter, but return something that is obviously wrong
    return Brushes.Yellow;
  }

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
    throw new NotImplementedException();
   }
} 

众所周知,格式化 WPF 数据网格非常困难,Microsoft 文档也没有告诉您如何操作。要更好地理解如何轻松格式化数据网格的不同部分,请阅读我的文章 CodeProject: Guide to WPF DataGrid formatting using bindings