C# 按Int或Float值排序DataGridTextColumn,而不是按原始字符串排序

C# 按Int或Float值排序DataGridTextColumn,而不是按原始字符串排序,c#,wpf,.net-core,datagrid,C#,Wpf,.net Core,Datagrid,我正在使用DataGrid并通过编程方式生成包含代码隐藏的列。 这些列派生自DataGridTextColumn,并添加了一些用于将键输入锁定到特定类型的内容 我需要对列进行数字排序: 1 2 10 11 而不是默认的基于字符串的排序: 1 10 11 2 我尝试了DataGridSortingEvent,但它无法从BindingListCollectionView强制转换到IList ListCollectionView lcv = new ListCollectionView((ILis

我正在使用DataGrid并通过编程方式生成包含代码隐藏的列。 这些列派生自DataGridTextColumn,并添加了一些用于将键输入锁定到特定类型的内容

我需要对列进行数字排序:

1
2
10
11
而不是默认的基于字符串的排序:

1
10
11
2
我尝试了DataGridSortingEvent,但它无法从BindingListCollectionView强制转换到IList

ListCollectionView lcv = new ListCollectionView((IList)CollectionViewSource.GetDefaultView(dataGrid.ItemsSource));
下面是我如何创建DataGrid的

DataSet set = new DataSet();
set.ReadXml(xmlDocument.CreateReader());

DataView data = set.Tables["row"];

dataGrid.ItemsSource = data;

这是我创建列的块

dataGrid.Columns.Add(new DataChimpIntegerColumn()
                            {
                                Header = column.ColumnTitle,
                                Binding = new Binding(column.ColumnTitle),
                                MaxWidth = 150,
                                DefaultValue = column.ColumnDefault,
                            });
和事件块

private void dataGrid_Sorting(object sender, DataGridSortingEventArgs e)
{
    DataGridColumn column = e.Column;
    IComparer comparer = null;

    if (e.Column.SortMemberPath != "id") return;

    e.Handled = true;

    ListSortDirection direction = (column.SortDirection != ListSortDirection.Ascending) 
        ? ListSortDirection.Ascending : ListSortDirection.Descending;

    column.SortDirection = direction;

    //    Error --> 
    ListCollectionView lcv = new ListCollectionView((IList)CollectionViewSource
        .GetDefaultView(dataGrid.ItemsSource));

    comparer = new SortNumerical(direction);

    lcv.CustomSort = comparer;
}
确切的错误消息是:

System.InvalidCastException: 'Unable to cast object of type 'System.Windows.Data.BindingListCollectionView' to type 'System.Collections.IList'.'

找到了一个有效的解决方案

将ItemsSource类型更改为
ObservableCollection
允许我根据加载的XML文件动态创建类(感谢C#6)


然后我可以直接使用
ListCollectionView lcv=newlistcollectionview(xmlData.ItemsSource作为IList)

找到了一个有效的解决方案

将ItemsSource类型更改为
ObservableCollection
允许我根据加载的XML文件动态创建类(感谢C#6)

然后我可以直接使用
ListCollectionView lcv=newlistcollectionview(xmlData.ItemsSource作为IList)

答案 在创建列的过程中,您应该能够指定
SortMemberPath
,因为您的自定义列来自
DataGridTextColumn
。但是,这意味着您必须访问要排序的值的整数表示形式

在我的测试中,我对列进行了编程初始化:

this.deviceLogDataGrid.Columns.Add(new DataGridTextColumn()
{
    Header = "Error Number",
    Binding = new Binding(nameof(DeviceLogRowVM.ErrorNumberString)),
    MaxWidth = 150,
    // DefaultValue = column.ColumnDefault,
    SortMemberPath = nameof(DeviceLogRowVM.ErrorNumber)
});
属性ErrorNumber是实际整数值,ErrorNumberString是该值的字符串表示形式。我使用
nameof
表达式以使重构属性名称更加安全

或者 如果您只想使用字符串表示法来正确格式化文本,可以尝试在
绑定
对象上使用
StringFormat
属性。您的绑定初始化可能如下所示:

Binding = new Binding(nameof(DeviceLogRowVM.ErrorNumber)) { StringFormat = "ER-{0}" },
默认情况下(不使用
SortMemberPath
属性),这也会对列进行正确排序,因为绑定值实际上是一个整数,在显示之前刚刚格式化。如果您只想显示浮点的2位小数,但需要按全精度排序,则此选项非常有用。

回答 在创建列的过程中,您应该能够指定
SortMemberPath
,因为您的自定义列来自
DataGridTextColumn
。但是,这意味着您必须访问要排序的值的整数表示形式

在我的测试中,我对列进行了编程初始化:

this.deviceLogDataGrid.Columns.Add(new DataGridTextColumn()
{
    Header = "Error Number",
    Binding = new Binding(nameof(DeviceLogRowVM.ErrorNumberString)),
    MaxWidth = 150,
    // DefaultValue = column.ColumnDefault,
    SortMemberPath = nameof(DeviceLogRowVM.ErrorNumber)
});
属性ErrorNumber是实际整数值,ErrorNumberString是该值的字符串表示形式。我使用
nameof
表达式以使重构属性名称更加安全

或者 如果您只想使用字符串表示法来正确格式化文本,可以尝试在
绑定
对象上使用
StringFormat
属性。您的绑定初始化可能如下所示:

Binding = new Binding(nameof(DeviceLogRowVM.ErrorNumber)) { StringFormat = "ER-{0}" },
默认情况下(不使用
SortMemberPath
属性),这也会对列进行正确排序,因为绑定值实际上是一个整数,在显示之前刚刚格式化。如果只想显示浮点的2位小数,但需要按全精度排序,则此选项非常有用