BindingList.Sort() 的行为类似于 List.Sort()
我正在尝试编写一个可用于我的应用程序的 SortableBindingList。 我发现了很多关于如何实现基本排序支持的讨论,以便 BindingList 在 DataGridView 或其他一些绑定控件的上下文中使用时进行排序,包括来自 StackOverflow 的这篇文章:
DataGridView 排序和例如 BindingList
这一切都非常有帮助,我已经实现了代码,经过测试等,并且一切正常,但在我的特殊情况下,我需要能够支持对 Sort() 的简单调用并具有该调用使用默认的 IComparable.CompareTo() 进行排序,而不是调用 ApplySortCore(PropertyDescriptor, ListSortDirection)。
原因是因为我有大量依赖于 Sort() 调用的代码,因为这个特定的类最初继承自 List,最近更改为 BindingList。
具体来说,我有一个名为 VariableCode 的类和一个名为 VariableCodeList 的集合类。 VariableCode 实现了 IComparable,并且其中的逻辑基于多个属性等而相当复杂...
public class VariableCode : ... IComparable ...
{
public int CompareTo(object p_Target)
{
int output = 0;
//some interesting stuff here
return output;
}
}
public class VariableCodeList : SortableBindingList<VariableCode>
{
public void Sort()
{
//This is where I need help
// How do I sort this list using the IComparable
// logic from the class above?
}
}
我在 Sort() 中重新利用 ApplySortCore 方法进行了几次失败的尝试,但一直阻碍我的是 ApplySortCore 期望PropertyDescriptor 进行排序,但我不知道如何使用 IComparable.CompareTo() 逻辑。
有人能指出我正确的方向吗?
非常感谢。
编辑:这是基于 Marc 响应的最终代码,以供将来参考。
/// <summary>
/// Sorts using the default IComparer of T
/// </summary>
public void Sort()
{
sort(null, null);
}
public void Sort(IComparer<T> p_Comparer)
{
sort(p_Comparer, null);
}
public void Sort(Comparison<T> p_Comparison)
{
sort(null, p_Comparison);
}
private void sort(IComparer<T> p_Comparer, Comparison<T> p_Comparison)
{
m_SortProperty = null;
m_SortDirection = ListSortDirection.Ascending;
//Extract items and sort separately
List<T> sortList = new List<T>();
this.ForEach(item => sortList.Add(item));//Extension method for this call
if (p_Comparison == null)
{
sortList.Sort(p_Comparer);
}//if
else
{
sortList.Sort(p_Comparison);
}//else
//Disable notifications, rebuild, and re-enable notifications
bool oldRaise = RaiseListChangedEvents;
RaiseListChangedEvents = false;
try
{
ClearItems();
sortList.ForEach(item => this.Add(item));
}
finally
{
RaiseListChangedEvents = oldRaise;
ResetBindings();
}
}
I am attempting to write a SortableBindingList that I can use for my application. I have found lots of discussion about how to implement basic sorting support so that the BindingList will sort when used in the context of a DataGridView or some other bound control including this post from StackOverflow:
DataGridView sort and e.g. BindingList<T> in .NET
This is all very helpful and I have implemented the code, tested, etc. and it's all working, but in my particular situation, I need to be able to support a simple call to Sort() and have that call use the default IComparable.CompareTo() to do the sorting, rather than making a call to ApplySortCore(PropertyDescriptor, ListSortDirection).
The reason is because I have quite a great deal of code that's depending on the Sort() call because this particular class originally inherited from List and was recently changed to be a BindingList.
So specifically, I have a class called VariableCode and a collection class called VariableCodeList. VariableCode implements IComparable and the logic in there is moderately complex based on several properties, etc...
public class VariableCode : ... IComparable ...
{
public int CompareTo(object p_Target)
{
int output = 0;
//some interesting stuff here
return output;
}
}
public class VariableCodeList : SortableBindingList<VariableCode>
{
public void Sort()
{
//This is where I need help
// How do I sort this list using the IComparable
// logic from the class above?
}
}
I've made a few failed attempts at repurposing the ApplySortCore method in the Sort(), but what keeps thwarting me is that the ApplySortCore expects a PropertyDescriptor to do its sort and I can't figure out how to get that to use the IComparable.CompareTo() logic.
Can someone point me in the right direction?
Many thanks.
EDIT: This is the final code based on Marc's response for future reference.
/// <summary>
/// Sorts using the default IComparer of T
/// </summary>
public void Sort()
{
sort(null, null);
}
public void Sort(IComparer<T> p_Comparer)
{
sort(p_Comparer, null);
}
public void Sort(Comparison<T> p_Comparison)
{
sort(null, p_Comparison);
}
private void sort(IComparer<T> p_Comparer, Comparison<T> p_Comparison)
{
m_SortProperty = null;
m_SortDirection = ListSortDirection.Ascending;
//Extract items and sort separately
List<T> sortList = new List<T>();
this.ForEach(item => sortList.Add(item));//Extension method for this call
if (p_Comparison == null)
{
sortList.Sort(p_Comparer);
}//if
else
{
sortList.Sort(p_Comparison);
}//else
//Disable notifications, rebuild, and re-enable notifications
bool oldRaise = RaiseListChangedEvents;
RaiseListChangedEvents = false;
try
{
ClearItems();
sortList.ForEach(item => this.Add(item));
}
finally
{
RaiseListChangedEvents = oldRaise;
ResetBindings();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
仅仅为了进行排序而模拟一个属性可能有点矫枉过正。
首先要查看的是
Comparer.Default
。 然而,最简单的做法可能是:List
或类似的顺便说一句,您也应该在现有排序过程中禁用通知。
Emulating a property just to do the sort is probably overkill.
The first thing to look at is
Comparer<T>.Default
. It might, however, turn out that the easiest thing to do is to:List<T>
or similarbtw, you should be disabling notifications during your existing sort, too.
我遇到了同样的问题,这篇文章帮助我解决了!
当我实现这个解决方案(基于 Marc 和 Paul 的代码)作为扩展并添加两个简单的排序方法时,我想与您分享:
希望这有帮助。
I had the same problem and this post helped me solve it!
As I implemented this solution (based on Marc's and Paul's code) as an extension and added two simple sort methods, I would like to share it with you:
Hope this is helpful.