意外地以相反的顺序获取可观察列表的项目

时间:2012-06-07 16:22:42

标签: c# data-binding binding observablecollection

我正在使用自定义的可观察集合类(信用转到Dean Chalke:http://www.deanchalk.me.uk/post/Thread-Safe-Dispatcher-Safe-Observable-Collection-for-WPF.aspx),以便从UI线程以外的线程修改数据绑定集合。

此自定义可观察集合实现了IList<>和INotifyCollectionChanged并包含IList<>类型的集合它存储了实际(周围)可观察集合的所有元素。

当我将此自定义可观察集合绑定到WPF列表时,可观察列表的项目正在正确显示,除非它们的顺序相反!

在运行时期间查看我的代码,提供IList<>类型的嵌入式集合的项目。驻留在自定义可观察集合中的具有正确的顺序。但是当我查看自定义可观察列表时,它的项目顺序相反。

也许我应该发布一些代码以使其更清晰:)

这是自定义可观察集合:

public class ThreadSaveObservableCollection <T> : IList<T>, INotifyCollectionChanged {

     private IList<T> collection;

     public ThreadSaveObservableCollection () {

         collection = new List<T>();
     }

     ...

     public void Insert (int index, T item) {

        if (Thread.CurrentThread == uiDispatcher.Thread) {

            insert_(index, item);
        } else {

            uiDispatcher.BeginInvoke(new Action<int, T>(insert_), DispatcherPriority.Normal, new object[] {index, item});
        }
    }

    private void insert_ (int index, T item) {

        rwLock.AcquireWriterLock(Timeout.Infinite);

        collection.Insert(index, item);
        CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));

        rwLock.ReleaseWriterLock();
    }

    ...
}

这是我在ViewModel中使用该集合的地方:

...
public ThreadSaveCollection Log {get; set;}

public ViewModel () {

    Log = new ThreadSaveCollection();
}
...

public void Insert() {

     log.Instert(0, "entry1");
}

我动态地在对象日志和WPF控件之间创建绑定:

LogList.ItemSource = ViewModel.Log;

除了这个错误的订单问题,一切似乎都运行得很好:线程做了他们应该做的事情,WPF列表及时更新。

再次进入代码时,ViewModel的Log对象向我显示反向顺序,而ThreadSaveObservableCollection中的集合对象具有正确顺序的项目。

我真的很感激任何帮助! 提前谢谢你......

UPDATE:语句log.Instert(0,“entry1”);是有意的,因为我希望有一个列表,随着时间的推移获取项目,每个新项目应插入列表的开头。换句话说,最新的项目始终位于列表的顶部。然而,在我的代码中,嵌入式集合具有所需的顺序,而周围的集合则没有。

为什么项目的顺序会有所不同?

更新:有趣的是,当我使用Add()而不是insert时,订单不会从外部集合中反转。

换句话说:无论我使用Add(item)还是Insert(0,item),我总是在我的ViewModel的ThreadSaveObservableCollection对象中得到相同的项目顺序,而内部包含的集合具有正确的顺序。 / p>

3 个答案:

答案 0 :(得分:1)

您似乎总是在索引0处插入新记录

log.Inster(0, "entry1");

创建先进先出的方案。

如果您插入

一个 乙 ç

你会回来的

C B A

答案 1 :(得分:0)

当您致电Insert(0, "entry1")时,您将新值放在列表的开头,这就是订单被撤消的原因。您可以改用Add方法。

答案 2 :(得分:0)

要在WPF组件中获得正确的顺序,可以使用SortDescription:

yourListView.Items.SortDescriptions.Add( new SortDescription( "yourSourcePropertyToOrderBy", ListSortDirection.Ascending ) );

您可以直接在WPF后面的代码中使用gui-management oder设置SortDescription。