Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF TreeView databinding to hide/show expand/collapse icon

I implemented a WPF load-on-demand treeview like described in this (very good) article. In the mentioned solution a dummy element is used to preserve the expand + icon / treeview item behavior. The dummy item is replaced with real data, when the user clicks on the expander.

I want to refine the model by adding a property public bool HasChildren { get { ... } } to my backing TreeNodeViewModel.

Question:
How can I bind this property to hide/show the expand icon (in XAML)? I am not able to find a suitable trigger/setter combination.
(INotifyPropertyChanged is properly implemented.)

Thanks for your time.

Update 1:
I want to use my property public bool HasChildren instead of using the dummy element.
Determining whether or not an item has children is somewhat costly, but still much cheaper than fetching the children.

like image 679
Julian Lettner Avatar asked Nov 05 '22 14:11

Julian Lettner


1 Answers

Julian,

this is a really good question. Why don't you try to write your own tree view item? :) I mean, not from the scratch, just derive from existing TreeViewItem and add your property. I have prepared a quick sample, but feel free to modify it as you wish (and ask questions if something is not perfectly clear). here we go:

public class TreeViewItem_CustomControl : TreeViewItem
{
    static TreeViewItem_CustomControl()
    {
        HasChildrenProperty = DependencyProperty.Register("HasChildren", typeof(Boolean), typeof(TreeViewItem_CustomControl));
    }

    static DependencyProperty HasChildrenProperty;

    public Boolean HasChildren
    {
        get
        {
            return (Boolean)base.GetValue(HasChildrenProperty);
        }

        set
        {
            if (value)
            {
                if (this.Items != null)
                {
                    this.Items.Add(String.Empty); //Dummy item
                }
            }
            else
            {
                if (this.Items != null)
                {
                    this.Items.Clear();
                }
            }

            base.SetValue(HasChildrenProperty, value);
        }

    }
}

This was the code for your custom TreeViewItem. Now let's use it in XAML:

<TreeView>
    <TreeViewItem Header="qwer">
        Regulat tree view item.
    </TreeViewItem>
    <CustomTree:TreeViewItem_CustomControl x:Name="xyz" Header="temp header" Height="50">
        <TreeViewItem>Custom tree view item, which will be removed.</TreeViewItem>
    </CustomTree:TreeViewItem_CustomControl>
</TreeView>

As you can see, first item is a regular one and the second is your custom one. Please note, that it has one child. Next, you can bind HasChildren property to some Boolean object in your ViewModel or just simply test my custom class by setting HasChildren to False from code behind the above XAML:

xyz.HasChildren = false;

Now, despite your element has one child, expand button is not displayed, so it means, that my custom class works.

I hope I helped you, but feel free to ask if you have any questions.

Piotr.

like image 55
Piotr Justyna Avatar answered Nov 14 '22 20:11

Piotr Justyna