【问题标题】:Sorting DataGridTextColumn by Int or Float value instead of raw string sort按 Int 或 Float 值而不是原始字符串排序对 DataGridTextColumn 进行排序
【发布时间】:2019-10-30 15:57:50
【问题描述】:

我正在使用 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'.'

【问题讨论】:

    标签: c# wpf .net-core datagrid


    【解决方案1】:

    找到一个可行的解决方案。

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

    然后我可以直接使用ListCollectionView lcv = new ListCollectionView(xmlData.ItemsSource as IList);

    【讨论】:

      【解决方案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 表达式是为了使重构属性名称更加安全。

      或者

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

      Binding = new Binding(nameof(DeviceLogRowVM.ErrorNumber)) { StringFormat = "ER-{0}" },
      

      这也将默认情况下(不使用SortMemberPath 属性)正确地对列进行排序,因为绑定值实际上是一个整数,它只是在显示之前被格式化。如果您只想显示浮点数的 2 位小数但需要按完整精度排序,则很有用。

      【讨论】:

        猜你喜欢
        • 2012-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-09
        • 1970-01-01
        • 2015-11-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多