2010-04-21 40 views
4

我遇到了一个问题,使用绑定到iBindingListView实现(第三方dll)的DataGridView附加到大集合。.net值类使用IComparable排序

我的集合类型中有一个属性,名为MyDateTime,它是一个类似于DateTime的值类,但也包含一些遗留代码。

该结构实现了iComparable,iComparable<T>iEquatable<T>

我遇到的问题是这样的:

当我应用排序的iBindingListViewMyDateTimeColumn,它总是使用非通用iComparer,造成成千上万的不必要的装箱和拆箱。

当我使用DGV提供的自动排序功能时,它会对列进行字符串排序。只保留这一列“自动”而不是编程仅用于此列是不可接受的。

当我删除非通用iComparer时,通用的仍然没有使用,它只是在.ToString()上进行字符串比较。

我错过了什么吗?为什么我的通用比较器不是bieng调用的?

+0

“value class”,你的意思是'struct'?或一个不可变的“类”? – 2010-04-21 14:51:03

+0

@Marc:因为他提到了拳击,听起来像'struct'。 – 2010-04-21 14:52:52

+0

@亚当 - 是的,我只是试图明确。 – 2010-04-21 14:56:07

回答

1

最终这种类型的数据绑定通常是基于反射的,反射是基于object的;所以拳击是一个现实。其实,你可以用来控制这个时候执行IBindingListView,但是它会是大量的工作,我猜他们根本没有(明智地)。

更简单的方法来做到这一点(我假设他们正在使用)是相信PropertyDescriptor,调用GetValue,然后使用Comparer.Default.Compare(x,y)。一旦你叫GetValue没有任何点而不是使用你已经装箱的对象(并将不得不然后unbox)。

如果你信任PropertyDescriptor你做了非常具体的实现代码,不支持一般ComponentModel对世界的看法(所以它不会在数据表或定制工作模型等)。

+0

我有点不确定你在哪里提到在我设置的模式中提到的“getvalue”,你能否详细说明一下?谢谢。 – greggorob64 2010-04-21 15:00:34

+0

@ greggorob64 - 'DataGridView'和'IBindingListView'基于一个抽象对象模型(通过'PropertyDescriptor')。例如,这是数据表如何将数据显示为“列”,而数据表*清楚*没有与您的逻辑列名相匹配的属性。 'PropertyDescriptor'有一个'GetValue(obj)'方法,这就是我所说的。同样,自动分类涉及它通过给予PropertyDescriptor实例来告诉哪些属性/属性应该涉及。 – 2010-04-21 15:09:00

+0

@ greggorob64 - 这也允许您通过'ICustomTypeDescriptor'或'TypeDescriptionProvider'添加自己的自定义模型。你可以通过'TypeDescriptor.GetProperties(someObject)'获得道具的* runtime *视图(或者有一个传递'Type'而不是一个实例的重载)。请注意,这里有很多其他接口。这是一个复杂而鲜为人知的框架角落。 – 2010-04-21 15:11:25

1

不幸的是,没有办法解决这个问题。在某些情况下,DataGridView将作为object来处理该值,这意味着如果它是值类型,则必须将其装箱。

+0

实际上,DataGridView通常不会通过'IBindingListView.ApplySort'将视图自己排序*问题在于编写不包含框的'ApplySort'实现是非常困难的。它可以完成,但它会很糟糕。 – 2010-04-21 14:53:45

+0

我想我不明白为什么排序在一个DateTime成员,具有相同的接口实现,可以完成没有拳击,但是当我使用myDateTime成员,它的确如此。 – greggorob64 2010-04-21 14:58:07

+0

@ greggorob64 - 它们可以特殊处理类似'DateTime'的预期类型;不太可能与您的自定义类型。我真的很惊讶,它甚至避免了拳击。 – 2010-04-21 15:00:19