我正在尝试在空闲时间学习一些WPF,并且我已经启动并运行了一个应用程序,但是有一段时间让我望而却步的事情是如何为可能出现的几个数据网格设置样式在页面上,基于他们将共享的列的行值。
意图是我可以根据货币金额是正数还是负数来设置整行的文本颜色(Foreground
属性)。
到目前为止我能够得到的单对硬编码值,我遇到的问题是连接到一个转换器,它将进行我想要的比较,以便返回真/假... < / p>
这是我到目前为止所做的:
<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个不同的时间,具有不同的数据排列。网格本身都按预期工作。
数据网格中填充了此类的集合:
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();
}
}
但是,我似乎无法获得datagrid的列与此转换器之间的绑定。这是我迄今为止所尝试的,基于在其他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
中设置这个样式内容,并从与其相关的数据网格中引用它。
答案 0 :(得分:0)
我通过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>
答案 1 :(得分:0)
在我看来,使用2个触发器进行绿色或读取时,您的方法有点复杂。你的转换器也可以返回颜色,你不需要触发器。
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