对ObservableCollection进行排序的问题在于,每次更改集合时,都会触发事件。所以对于一种从一个位置移除物品并将它们添加到另一个位置的行为,最终会发生大量事件。
我认为你最好打赌就是只要按正确的顺序插入ObservableCollection开始。从集合中删除项目不会影响订购。我刮起了快速的扩展方法来说明
public static void InsertSorted<T>(this ObservableCollection<T> collection, T item, Comparison<T> comparison)
{
if (collection.Count == 0)
collection.Add(item);
else
{
bool last = true;
for (int i = 0; i < collection.Count; i++)
{
int result = comparison.Invoke(collection[i], item);
if (result >= 1)
{
collection.Insert(i, item);
last = false;
break;
}
}
if (last)
collection.Add(item);
}
}
所以,如果你使用的字符串(例如),代码看起来像这样
ObservableCollection<string> strs = new ObservableCollection<string>();
Comparison<string> comparison = new Comparison<string>((s1, s2) => { return String.Compare(s1, s2); });
strs.InsertSorted("Mark", comparison);
strs.InsertSorted("Tim", comparison);
strs.InsertSorted("Joe", comparison);
strs.InsertSorted("Al", comparison);
编辑
你可以如果扩展ObservableCollection并提供您自己的插入/添加方法,请保持呼叫相同。类似这样的:
public class BarDataCollection : ObservableCollection<BarData>
{
private Comparison<BarData> _comparison = new Comparison<BarData>((bd1, bd2) => { return DateTime.Compare(bd1.StartDate, bd2.StartDate); });
public new void Insert(int index, BarData item)
{
InternalInsert(item);
}
protected override void InsertItem(int index, BarData item)
{
InternalInsert(item);
}
public new void Add(BarData item)
{
InternalInsert(item);
}
private void InternalInsert(BarData item)
{
if (Items.Count == 0)
Items.Add(item);
else
{
bool last = true;
for (int i = 0; i < Items.Count; i++)
{
int result = _comparison.Invoke(Items[i], item);
if (result >= 1)
{
Items.Insert(i, item);
last = false;
break;
}
}
if (last)
Items.Add(item);
}
}
}
插入索引被忽略。
BarData db1 = new BarData(DateTime.Now.AddDays(-1));
BarData db2 = new BarData(DateTime.Now.AddDays(-2));
BarData db3 = new BarData(DateTime.Now.AddDays(1));
BarData db4 = new BarData(DateTime.Now);
BarDataCollection bdc = new BarDataCollection();
bdc.Add(db1);
bdc.Insert(100, db2);
bdc.Insert(1, db3);
bdc.Add(db4);
这是一次性任务,即在收集绑定到控件之前可以完成的任务吗? –
集合即使在绑定时也会保持更改(这就是我使用ObservableCollection的原因,以便在集合更改时更新UI)。解决这个问题的一个选择是在向收藏中添加项目时处理它,以确保按照排序顺序将其插入到适当的索引中,或者第二个选项是在添加或删除项目时对收集进行排序。我想在这里评估第二个选项。 –
在我看来,这是一个设计缺陷,对象本身知道到现在为止花了多少钱,而且这些信息取决于排序。这应该是用户控件中的一个功能('ShowTotal = true')。 –