C# 未按预期调用重写的winform ListBox.Sort()
我试图覆盖列表框中的sort方法以按降序排序 代码: 现在,我直觉地认为,只要将项添加到列表中,就会调用此方法,并且当ListBox.Sorted=true时,它似乎就是这样处理基本ListBox的。但是,在将项目添加到列表后使用my CustomSortListBox时,我的自定义排序没有得到遵守,而且,当项目列表更改时,重写的方法没有被调用,甚至没有命中断点 然后我读了这篇文章,它说“别忘了,只有当排序属性从false变为true时,才会调用Sort”。这对我来说似乎很神奇,但可以肯定的是,当切换Sorted off和back on时,我的自定义排序会被调用并起作用 有趣的是,在此之后,保留Sorted=true,使用base Sort()方法对添加的新项进行排序,从而创建升序项和降序项的混合。直到您再次切换排序为false->true 我甚至会接受将排序=假的老套解决方案;排序=真;在ItemsChanged的事件处理程序中,但这样的事件不存在 我做错了什么?当列表添加到时,我如何使此排序覆盖得到尊重C# 未按预期调用重写的winform ListBox.Sort(),c#,winforms,sorting,listbox,C#,Winforms,Sorting,Listbox,我试图覆盖列表框中的sort方法以按降序排序 代码: 现在,我直觉地认为,只要将项添加到列表中,就会调用此方法,并且当ListBox.Sorted=true时,它似乎就是这样处理基本ListBox的。但是,在将项目添加到列表后使用my CustomSortListBox时,我的自定义排序没有得到遵守,而且,当项目列表更改时,重写的方法没有被调用,甚至没有命中断点 然后我读了这篇文章,它说“别忘了,只有当排序属性从false变为true时,才会调用Sort”。这对我来说似乎很神奇,但可以肯定的是,
(我看到了,但他的问题还不清楚,似乎已经“消失”了,他随机选择的答案并不理想,甚至由于无法访问保护级别而无法编译)您似乎明白,要调用
Sort()
方法,列表框。Sorted
属性需要转换为true
。这是记录在案的,尽管很差。据我所知,这是唯一一次调用Sort()
方法,这种理解与文档是一致的
有趣的是,在此之后,保留Sorted=true,使用base Sort()方法对添加的新项进行排序,从而创建升序项和降序项的混合。直到您再次切换排序为false->true
将项添加到列表框中时,顺序不是由Sort()
方法处理的,而是由控件的集合对象处理的。此对象执行二进制搜索以找到插入新项的正确位置。不幸的是,在列表框项文本上使用字符串比较是硬编码的
这就是为什么添加项会使它们按照默认实现排序。但它并没有使用“baseSort()
方法”来完成
对于WinformsListBox
类,如果希望有效地排序项目,最好不要覆盖Sort()
或使用sorted
属性。相反,提供一个助手方法来添加新项目,并让该方法在项目
集合上执行适当的二进制搜索以查找插入位置
无论如何,您都必须实现一个helper方法来获得添加项的通知,并且进行排序插入比每次插入时对整个集合重新排序更有效
您可以(如注释中所建议的)将已排序的集合绑定到列表框中,但这将需要更多的工作,特别是因为AFAIK没有任何内置的集合类型支持绑定并且固有地进行排序。不必从MSDN文章中复制粘贴代码。您只需指出,您希望在每次添加items时调用一些自定义的Sort
方法,以符合@SergeyBerezovskiy!关于这个“复制粘贴”问题,我也打算这么说(回复:)。另外,问题海报到底在问什么?澄清一下会有帮助的。值得一提的是,查看ListBox源代码,您可以看到Add方法没有调用Sort,它只是调用(内部)BinarySearch方法来获取放置新项的索引。所以重写sort不会有帮助。但是为什么要对列表框进行排序呢。对我来说,列表框是用来显示数据而不是排序数据的。如果要排序,请将数据放入列表中,对该列表进行排序,并将该列表绑定到ListBox。这种行为有很好的文档记录。这样工作有一个很好的理由,本地ListBox控件保留其自己的列表中显示的字符串副本。因此,为了对它们进行排序,必须首先清空该列表,然后按照排序顺序重新添加已排序的项。这是非常昂贵的,太昂贵了,不能每次添加一个项目时都这样做。@SergeyBerezovskiy这实际上与MSDN上的代码不同。但我明白你的意思,那篇文章其实并不需要它。
public CustomSortListBox()
: base()
{
}
protected override void Sort()
{
if (this.Items.Count > 1)
{
bool swapped;
do
{
int counter = this.Items.Count - 1;
swapped = false;
while (counter > 0)
{
// set this to != to reverse sorting
if (this.Items[counter].ToString().CompareTo(this.Items[counter - 1].ToString()) != -1)
{
object temp = Items[counter];
this.Items[counter] = this.Items[counter - 1];
this.Items[counter - 1] = temp;
swapped = true;
}
counter -= 1;
}
}
while (swapped);
}
}