我有以下自定义可观察集合(代码部分来自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;
除了相对于ViewModel的Collection对象中的项目反转wpf列表控件中的项目顺序这一事实外,一切正常。
使用语句Collection.Insert(0,intem)我希望在列表顶部添加新项目,但我得到的结果与使用Collection.Add(item)的结果相同。
当我在运行期间进入代码时,我可以验证我的Collection中的项目是否按正确顺序排列,但是在wpf list控件内的表面上,顺序被更改,即反转。
我做错了什么?
我想这个问题必须在数据绑定的某处找到,因为它是连接我的ObservableCollection和wpf控件的'wire',似乎正确的顺序进入了连线,而且不正确就是离开它。
可能它与IList接口的GetEnumerator()方法有关,因为wpf控件的ItemSource属性正在等待枚举器?
我不知道,我真的被卡住了......
提前感谢您的帮助......
答案 0 :(得分:1)
你可以尝试这样做:
http://msdn.microsoft.com/en-us/library/ms653208.aspx
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, new List<object>() { item }, 0));
我认为这个事件就是问题所在。
答案 1 :(得分:1)
关于你的代码的几点说明:
最后,我建议使用其中一个thread-safe ObservableCollections而不是重新发明轮子。