2

データバインドされた TreeView があります。TreeViewItems を拡張したいのですが、深さは 3 としましょう。

通常、私は TreeViewItem.ExpandSubtree() を発行しますが、それはすべてを展開するので、かなり単純なはずなので、自分で作ってみましたか?

これが私が試したものです。以下のメソッドを作成し、ツリービュー ItemContainerGenerator とツリービューの項目コレクションを深さ 3 で渡します。

private void ExpandTree(ItemContainerGenerator gen, ItemCollection items, int depth)
{
    depth--;
    foreach (var item in items)
    {
        TreeViewItem itm = (TreeViewItem)gen.ContainerFromItem(item);
        if (itm == null) continue;
        itm.IsExpanded = true;


        if(depth!=0 && itm.Items.Count > 0) ExpandTree(itm.ItemContainerGenerator,itm.Items,depth);
    }
}

問題は、最初にすべてのサブアイテムの ItemContainerGenerator を再帰的にコールバックすると、ステータスが「NotStarted」になり、呼び出されるたびに null が返されることです。ヌルをトラップしている間、ツリーは必要な深さ 3 ではなく深さ 1 までしか開かないことを意味します。

ここで何が欠けていますか?

4

1 に答える 1

3

子 ItemContainerGenerator に孫を作成する時間を与えるための遅延がありません。解決策は、データ バインディング インフラストラクチャの実行時間が経過したで、WPF ディスパッチャーに再帰呼び出しをスケジュールするように依頼することです。

Action recurse = () => ExpandTree(itm.ItemContainerGenerator, itm.Items, depth);
itm.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, recurse);  // note the priority

ここで、デリゲートが呼び出されるまでに、ItemContainerGenerator を実行する時間があり、コンテナーが使用可能になります。

おそらく、子 ItemContainerGenerator の StatusChanged イベントをサブスクライブする (そしてそこから再帰呼び出しを行う) ことによってもこれを行うことができますが、私はこのアプローチを試していません。

于 2011-02-01T00:33:16.960 に答える