WPF Datagrid右对齐数字列

我正在尝试为我的应用程序中的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中的所有列,检查绑定,推断绑定到的属性的类型,并将右对齐应用于列.这将避免创建永远不会触发或永久触发的触发器,并且可能适合每个列仅包含一种类型的数据的情况.但是,这种方法仍然需要代码隐藏,需要传递每行绑定的类型,如果绑定属性路径涉及的不仅仅是单个属性名称,则会变得复杂.

我担心我无法看到只使用样式的问题的解决方案,并避免代码隐藏.

点赞