次のカスタム監視可能なコレクションがあります (コードは 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 コントロール (通常のリスト コントロール) を動的に作成するため、コード ビハインドでデータ バインディングを適用します。
wpfContainer.LogList.ItemsSource = viewModel.Collection;
wpf リスト コントロール内の項目の順序が、ViewModel の Collection オブジェクト内の項目に対して逆になっているという事実を除いて、すべてが正常に機能します。
ステートメント Collection.Insert(0, intem) を使用すると、リストの一番上に新しいアイテムを追加することが期待されますが、Collection.Add(item) を使用した場合と同じ結果が得られます。
実行時にコードにステップインすると、コレクション内のアイテムが正しい順序になっていることを確認できますが、wpf リスト コントロール内の表面では順序が変更されています。つまり、逆になっています。
私は何を間違えていますか?
私のObservableCollectionをwpfコントロールに接続するのは「ワイヤ」であり、正しい順序がワイヤに入り、間違った順序がワイヤを離れているように見えるため、問題はデータバインディングのどこかにあるはずだと思います。
wpf コントロールの ItemSource プロパティが Enumerator を待っているため、IList インターフェイスの GetEnumerator() メソッドと関係があるのでしょうか。
私には手がかりがなく、本当に立ち往生しています...
助けてくれてありがとう...