WPF ListBox ListCollectionView 匿名类型导航问题
问题示例:
框架: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; }
}
谢谢
Example of problem:
Framework: WPF
Visual control: DataGrid from CodePlex
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();
}
The DataGrid cursor doesn't change position to 1, if change a value of one of anonymous types:
var listView = new ListCollectionView(
new[]
{
new
{
Bool = false,
Str = "Value1"
},
new
{
Bool = false,
Str = "Value2"
}
}.ToList());
Cursor works correct and SelectedIndex = 1.
I think it happens because of anonymous object override GetHashCode()
For anonymous object GetHashCode: sum of all fields. If fields are the same for 2 different instances of anonymous objects GetHashCode() will return the same value for both instances.
Maybe DataGrid internally compares objects using GetHashCode and doesn't change SelectedPosition.
Does anybody know how avoid this problem?
Assigning anonymous objects to DataGrid is requirement, I can't create strongly typed objects, which means I have to create a wrapper for the object and autogenerate the columns:
public class ViewItemHodler
{
public object ViewItem { get; set; }
}
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
DataGrid 上有一个 CustomSort 属性,您可以将其设置为
IComparer
的实现,这将允许您为匿名类型实现自定义排序顺序。 有关 CustomSort 属性的更多信息,请参见:http://blogs.msdn.com/jgoldb/archive/2008/08/26/improving-microsoft-datagrid-ctp-sorting-performance.aspx
您想要做的是实际上创建一个 shell 类,该类接受
Comparer
委托,然后在IComparer.Compare
的实现中调用该委托。这样,您可以在创建匿名类型的代码中使用 var 声明实例(因为您不知道 T 是什么)。
绑定到匿名类型并且无法创建强类型对象的想法有点荒谬。 您不会从编译时未知的源创建匿名查询,因此我不明白为什么要限制匿名类型。
There is a CustomSort property on the DataGrid which you can set to an implementation of
IComparer<T>
which will allow you to implement a custom sort order for your anonymous types. There is more info on the CustomSort property here:http://blogs.msdn.com/jgoldb/archive/2008/08/26/improving-microsoft-datagrid-ctp-sorting-performance.aspx
What you will want to do is actually create a shell class which takes a
Comparer<T>
delegate and then calls that in the implementation ofIComparer<T>.Compare
.This way, you can use var to declare the instance (since you won't know what T is) in your code that creates the anonymous type.
The idea that you are bound to anonymous types and can't create strongly typed objects is a little ridiculous. You aren't creating anonymous queries from a source that isn't known at compile time, so I don't see why the restriction on anonymous types.