在ListBox中绑定一个已排序的ObservableCollection<T>

8
我在我的Windows Phone 7应用程序中有一个数据对象列表,名为MyObjectList,它继承了ObservableCollection<MyObject>。我将该列表保留在App的公共属性MyObjects中。我的目标是将数据绑定到ListBox并按MyObject.Name排序。

目前,我在XAML中有一个名为MyObjectsListListBox,并在构造函数中使用以下代码进行链接:

public MyObjectListView()
{
    InitializeComponent();
    this.MyObjectsList.ItemsSource = ((App)App.Current).MyObjects;
}

这很好用。我添加了MyObjects中的项目,它们出现在ListBox中。然而,在列表中显示时,数据没有按名称排序。我尝试了以下更改以使数据排序:

this.MyObjectsList.ItemsSource = ((App)App.Current).MyObjects
                                         .OrderBy(x => x.Name)

但是当我这样做时,我在ListBox中看不到任何已排序或未排序的对象。

我该怎么办才能让我添加到ObservableCollection的项目按.Name排序后显示在ListBox中?


4
在ItemsSource上使用Linq会禁用ObservableCollection的“可观察”功能。 - Ana Betts
4个回答

11

你例子中的问题在于OrderBy方法返回的是IOrderedEnumerable类型的对象,而不是ObservableCollection类型。

以下是一些你可以尝试的方式,而无需像其他答案中那样实现一个自定义集合。

var sortedMyObjects = new ObservableCollection<MyObject>();
foreach (var myobj in ((App)App.Current).MyObjects.Orderby(x => x.Name))
    sortedMyObjects.Add(myobj);
this.MyObjectsList.ItemsSource = sortedMyObjects;

其他答案都提出了可行的替代方案,但这个解决方案将解决问题。

顺便说一句,在Silverlight 4中有一个PagedCollectionView,但Windows Phone 7的Silverlight基于Silverlight 3,因此不可用。我只是提到这一点,让你预见到WP7最终将更新为SL4。


这对我来说非常有效!我将所有的代码都转换为利用它。 - pearcewg

4

这个实现非常糟糕,因为它在已排序的集合上进行O(n)插入。我绝对不建议使用它。 - Benlitz
我认为没有人会拥有足够大的集合,以至于O(n)成为一个问题。 - roim

1

这对Silverlight没有帮助,但对于WPF 3.5/4,有一种更好的方法可以通过CollectionView实现。


0

你提供的第一个链接指向了一篇关于使用<CollectionViewSource .../>的好文章。一旦我弄清楚了要使用的正确命名空间(这在XAML中总是一个挑战),它就完美地工作了。谢谢! - Ben McCormack
1
第一个链接似乎已经失效。 - vwegert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接