我正在尝试为我的应用程序中的DataGrid单元格创建样式.我知道可能有一种方法可以使用DataTrigger在DataGrid中对齐数字单元格.这甚至可能吗?
我的DataGrid的样式是这样的:
<Style TargetType="{x:Type DataGrid}">
<Setter Property="AlternatingRowBackground">
<Setter.Value>
<SolidColorBrush Color="#CCCCCC" />
</Setter.Value>
</Setter>
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="CanUserDeleteRows" Value="False" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0" Color="#CCCCCC" />
<GradientStop Offset="1" Color="#FFFFFF" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="RowHeaderWidth" Value="0" />
<Setter Property="CellStyle">
<Setter.Value>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#7777FF" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>
我想可能在CellStyle上添加某种触发器来检测内容是否为数字(int,double,decimal,…)并相应地设置单元格的样式.这可能吗?
更新
考虑到这一点,我尝试了几件事,但它没有用.我尝试使用定义为的DataTrigger:
<DataTrigger Binding="{Binding Converter={StaticResource IsNumericConverter}}" Value="True">
<Setter Property="HorizontalContentAlignment" Value="Right" />
</DataTrigger>
IsNumericConverter的位置是:
public class IsNumericConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value is int || (value is decimal || value is double);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
但是当我在转换器上设置断点时,我得到的值是整行的类型,而不是每个单独的单元格……
最佳答案 一种方法是在代码隐藏中设置触发器.以下方法将触发器应用于DataGridColumn.此触发器使用您的IsNumericConverter来确定是否执行右对齐:
public static void AddTriggerToColumnStyle(DataGridColumn column)
{
var boundColumn = column as DataGridBoundColumn;
if (boundColumn != null && boundColumn.Binding is Binding)
{
string bindingPropertyPath = (boundColumn.Binding as Binding).Path.Path;
column.CellStyle = new Style()
{
BasedOn = column.CellStyle,
TargetType = typeof(DataGridCell),
Triggers =
{
new DataTrigger
{
Binding = new Binding(bindingPropertyPath) { Converter = new IsNumericConverter() },
Value = true,
Setters =
{
new Setter
{
Property = TextBlock.TextAlignmentProperty,
Value = TextAlignment.Right
}
}
}
}
};
}
}
在代码隐藏构造函数中的InitializeComponent()之后调用此方法应该是安全的.
如果列具有数字和非数字数据的混合,则此方法将起作用.如果列仅包含一种类型的数据,则此方法仍然有效,但创建的触发器将永远不会触发或永久触发.
当然,对于使用DataGrids的每个控件,不必在代码隐藏中重复上述方法.您可以将其移动到静态实用程序类,并让所有代码隐藏类调用此方法.您甚至可以添加一个静态实用程序方法,该方法遍历传递它的DataGrid中的列,并为每列调用上述方法.
更新:我修改了上面的方法,允许它推导出绑定属性路径.这使它更容易使用.我还将方法设置为public和static,以便可以将其移动到静态实用程序类.
我确实想到了另一种方法,它将遍历DataGrid中的所有列,检查绑定,推断绑定到的属性的类型,并将右对齐应用于列.这将避免创建永远不会触发或永久触发的触发器,并且可能适合每个列仅包含一种类型的数据的情况.但是,这种方法仍然需要代码隐藏,需要传递每行绑定的类型,如果绑定属性路径涉及的不仅仅是单个属性名称,则会变得复杂.
我担心我无法看到只使用样式的问题的解决方案,并避免代码隐藏.