0

カスタムの監視可能なコレクションクラス(クレジットは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内のコレクションオブジェクトには正しい順序のアイテムがあります。

助けていただければ幸いです。前もって感謝します ...

更新:ステートメントlog.Instert(0、 "entry1"); 時間の経過とともにアイテムを取得するリストが必要であり、すべての新しいアイテムをリストの先頭に挿入する必要があるため、これは意図的なものです。つまり、最新のアイテムが常にリストの一番上にあります。それにもかかわらず、私のコードでは、埋め込まれたコレクションには目的の順序がありますが、周囲のコレクションにはありません。

とにかくアイテムの順序に違いがあるのはなぜですか?

更新:興味深いことに、挿入の代わりにAdd()を使用すると、外部のコレクションから順序が逆になりません。

言い換えると、Add(item)またはInsert(0、item)のどちらを使用するかに関係なく、ViewModelのThreadSaveObservableCollectionオブジェクトで常に同じ順序のアイテムを取得していますが、内部に含まれるコレクションの順序は正しいです。

4

3 に答える 3

1

あなたは常にインデックス0で新しいレコードを挿入しているようです

log.Inster(0, "entry1");

先入れ先出しシナリオを作成します。

挿入した場合

A B C

あなたは戻ってきます

CBA

于 2012-06-07T16:25:10.960 に答える
0

電話Insert(0, "entry1")をかけると、リストの先頭に新しい値が表示されます。そのため、順序が逆になります。代わりにAddメソッドを使用できます。

于 2012-06-07T16:25:18.600 に答える
0

WPF コンポーネントで正しい順序を取得するには、SortDescription を使用できます。

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

WPF の背後にあるコードで、GUI 管理オーダーで SortDescription を直接セットアップできます。

于 2014-02-07T13:06:18.590 に答える