3

TreeViewコントロールがあり、オブジェクトの3層の大きなリストを入力する必要があります。これは、構築に非常に長い時間がかかります。バックグラウンドスレッドでデータの読み込みを行ってから、GUIの更新をGUIスレッドに送信していますが、更新が多すぎるため、ノードを追加するたびに、それを送信する必要があります。 ExpandSubTree()メソッドを呼び出して、すべてのサブノードを展開します。これにより、さらに展開イベントが発生し、クラッシュします。

コントロールを構築し、バックグラウンドスレッドで何らかの方法で開いた/閉じた状態にして、完了したらマーシャルする方法はありますか?

4

2 に答える 2

0

ツリー全体を一度に作成していますか?作成されたアイテムごとに呼び出しを起動していますか?

ツリーをオンデマンドでロードすることを考えます。たぶん、ユーザーがノードを拡張しようとすると、そのイベントを処理してデータを取得します。また、呼び出しごとにアイテムのグループをロードすることも検討します

于 2012-10-19T17:01:08.940 に答える
0

各ツリービューアイテムにはプロパティChildrenがあり、各ツリービューアイテムのChildrenをObservableCollectionにバインドすると、BackGroundWorkerまたは別のスレッドからアイテムを追加できます。followコレクションを使用してツリービューアイテムの子をバインドする場合は、子を追加することができます-子を背景からビューに削除します。同期コンテキストを使用して、ビューにアイテムを追加します。

public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
{
    private SynchronizationContext SynchronizationContext;

    public ThreadSafeObservableCollection()
    {
        SynchronizationContext = SynchronizationContext.Current;

        // current synchronization context will be null if we're not in UI Thread
        if (SynchronizationContext == null)
            throw new InvalidOperationException("This collection must be instantiated from UI Thread, if not, you have to pass SynchronizationContext to con                                structor.");
    }

    public ThreadSafeObservableCollection(SynchronizationContext synchronizationContext)
    {
        if (synchronizationContext == null)
            throw new ArgumentNullException("synchronizationContext");

        this.SynchronizationContext = synchronizationContext;
    }

    protected override void ClearItems()
    {
        this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.ClearItems()), null);
    }

    protected override void InsertItem(int index, T item)
    {
        this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.InsertItem(index, item)), null);
    }

    protected override void RemoveItem(int index)
    {
        this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.RemoveItem(index)), null);
    }

    protected override void SetItem(int index, T item)
    {
        this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.SetItem(index, item)), null);
    }

    protected override void MoveItem(int oldIndex, int newIndex)
    {
        this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.MoveItem(oldIndex, newIndex)), null);
    }
}

また、私はこの記事があなたに役立つに違いないと思います:

ViewModelパターンを使用したWPFTreeViewの簡素化

WPFのカスタムTreeViewレイアウト

これがあなたに役立つことを願っています...

于 2012-10-19T17:50:00.823 に答える