0

问题示例:

框架:WPF 可视化控件:来自 CodePlex 的 DataGrid

public Window()
{
  InitializeComponent();

  var listView = new ListCollectionView(
    new[]
    {
       new 
       {   
         Bool = false,
         Str = "Value1"
       },
       new 
       {   
          Bool = false,
          Str = "Value1"
       }
     }.ToList());

  dataGrid.ItemsSource = listView;

  listView.MoveCurrentToFirst();
  listView.MoveCurrentToNext();
}

如果更改其中一种匿名类型的值,则 DataGrid 游标不会将位置更改为 1:

var listView = new ListCollectionView(
    new[]
    {
       new 
       {   
         Bool = false,
         Str = "Value1"
       },
       new 
       {   
          Bool = false,
          Str = "Value2"
       }
     }.ToList());

光标工作正确且 SelectedIndex = 1。

我认为这是因为匿名对象覆盖 GetHashCode() 对于匿名对象 GetHashCode:所有字段的总和。如果匿名对象的 2 个不同实例的字段相同,则 GetHashCode() 将为两个实例返回相同的值。

也许 DataGrid 在内部使用 GetHashCode 比较对象并且不会更改 SelectedPosition。

有谁知道如何避免这个问题?将匿名对象分配给 DataGrid 是必需的,我无法创建强类型对象,这意味着我必须为对象创建一个包装器并自动生成列:

public class ViewItemHodler
{
   public object ViewItem { get; set; }
}

谢谢

4

1 回答 1

2

DataGrid 上有一个 CustomSort 属性,您可以将其设置为IComparer<T>允许您为匿名类型实现自定义排序顺序的实现。这里有关于 CustomSort 属性的更多信息:

http://blogs.msdn.com/jgoldb/archive/2008/08/26/improving-microsoft-datagrid-ctp-sorting-performance.aspx

你要做的实际上是创建一个 shell 类,它接受一个Comparer<T>委托,然后在IComparer<T>.Compare.

这样,您可以使用 var 在创建匿名类型的代码中声明实例(因为您不知道 T 是什么)。

你被绑定到匿名类型并且不能创建强类型对象的想法有点荒谬。您没有从编译时未知的来源创建匿名查询,所以我不明白为什么要限制匿名类型。

于 2009-03-02T18:28:32.697 回答