开发者

WPF Treeview Expand only to a certain depth?

I have a TreeView that is databound. I would like to expand the TreeViewItems but only to a depth of lets say 3.

Normally I would issue a TreeViewItem.ExpandSubtree() but that expands everything so I took a stab making my own as it should be fairly simple right?

Here is what I tried, I made the method below and then pass my treeviews ItemContainerGenerator to it and the items collection from the treeview, with a depth of 3.

private void ExpandTree(ItemContainerGenerator gen, ItemCollection items, int depth)
{
    depth--;
    foreach (var item in items)
    {
        TreeViewItem itm = (TreeViewItem)gen.ContainerFromItem(item开发者_如何学Go);
        if (itm == null) continue;
        itm.IsExpanded = true;


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

The problem is that the first time it recursively calls back the ItemContainerGenerator for all subitems has a status of "NotStarted" and returns null every time it is called. While I trap the null it means that the tree only opens to a depth of 1 and not the 3 I wanted.

What am I missing here?


You are missing a delay to give the child ItemContainerGenerator time to create the grandchildren. The solution is to ask the WPF dispatcher to schedule the recursive call after the data binding infrastructure has had time to run:

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

Now, by the time the delegate gets called, the ItemContainerGenerator will have had time to run, and the containers will be available.

You could probably also do this by subscribing to the child ItemContainerGenerator's StatusChanged event (and making the recursive call from there), but I haven't tried this approach.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜