我有以下自定义可观察集合(代码部分来自 Dean Chalk 的博客http://www.deanchalk.me.uk/post/Thread-Safe-Dispatcher-Safe-Observable-Collection-for-WPF.aspx和略有改动):
public class ThreadSaveObservableCollection <T> : IList<T>, INotifyCollectionChanged {
private IList<T> collection;
private Dispatcher uiDispatcher;
private ReaderWriterLock rwLock;
public ThreadSaveObservableCollection () {
collection = new List<T>();
rwLock = new ReaderWriterLock();
uiDispatcher = Dispatcher.CurrentDispatcher;
}
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();
}
public IEnumerator<T> GetEnumerator () {
rwLock.AcquireReaderLock(Timeout.Infinite);
IEnumerator<T> enumerator = collection.GetEnumerator();
rwLock.ReleaseReaderLock();
return enumerator;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () {
rwLock.AcquireReaderLock(Timeout.Infinite);
IEnumerator<T> enumerator = collection.GetEnumerator();
rwLock.ReleaseReaderLock();
return enumerator;
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
... // the remaining methods of the IList<> interface
}
此外,我有一个 ViewModel 包含此类的实例:
public class ViewModel {
private ThreadSaveObservableCollection<string> Collection {get; set;}
public ViewModel () {
Collection = new ThreadSaveObservableCollection<string>();
}
public void Insert (string item) {
Collection.Insert(0, item);
}
}
我在代码隐藏中应用数据绑定,因为我动态创建了名称为“LogList”的相应 WPF 控件(一个普通的 List 控件):
wpfContainer.LogList.ItemsSource = viewModel.Collection;
除了 wpf 列表控件中的项目顺序相对于 ViewModel 的 Collection 对象中的项目相反的事实之外,一切都工作得很好。
使用语句 Collection.Insert(0, intem) 我希望将新项目添加到列表的顶部,但我得到的结果与使用 Collection.Add(item) 的结果相同。
当我在运行时进入代码时,我可以验证我的 Collection 中的项目的顺序是否正确,但在 wpf 列表控件内部的表面上,顺序被改变了,即颠倒了。
我做错了什么?
我想问题必须在数据绑定周围的某个地方找到,因为它是将我的 ObservableCollection 与 wpf 控件连接起来的“线”,并且似乎正确的顺序正在进入线路并且不正确的顺序正在离开它。
也许它与 IList 接口的 GetEnumerator() 方法有关,因为 wpf 控件的 ItemSource 属性正在等待 Enumerator ?
我不知道,我真的被困住了......
预先感谢您的任何帮助 ...