WPF Treeview Развернуть только до определенной глубины? - PullRequest
2 голосов
/ 01 февраля 2011

У меня есть TreeView с привязкой к данным. Я хотел бы расширить TreeViewItems, но только на глубину, скажем, 3.

Обычно я выпускаю TreeViewItem.ExpandSubtree (), но он расширяет все, так что я сделал удар, делая свой собственный, как это должно быть довольно просто, верно?

Вот что я попробовал, я сделал метод ниже и затем передал ему свои TreeViews 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» и возвращает ноль при каждом вызове. В то время как я ловлю ноль, это означает, что дерево открывается только на глубину 1, а не на 3, который я хотел.

Что мне здесь не хватает?

1 Ответ

3 голосов
/ 01 февраля 2011

Вы упускаете задержку, чтобы дать дочернему ItemContainerGenerator время для создания внуков. Решение состоит в том, чтобы попросить диспетчера WPF запланировать рекурсивный вызов после , когда инфраструктура привязки данных успела выполнить:

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

Теперь к моменту вызова делегата у ItemContainerGenerator будет время для запуска, и контейнеры будут доступны.

Возможно, вы также могли бы сделать это, подписавшись на событие StatusChanged дочернего ItemContainerGenerator (и оттуда сделав рекурсивный вызов), но я не пробовал этот подход.

...