Click here to Skip to main content
15,868,016 members
Articles / Desktop Programming / WPF
Tip/Trick

Settings a TreeViewItem as not selectable

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
25 Jan 2013CPOL2 min read 19.3K   5  
Settings a TreeViewItem as not selectable.

Introduction

I had a need to set some items in a TreeView as not selectable as they were top items of different types. Since the items were not of type TreeViewItem I had some limitations on how to do it.

Using the code

Since I like MVVM, this will be done using behaviors. We need to take over the items before they are presented to the user. Behaviors add to the control some sort of "behavior" and by that we are able to control how it responds to actions in our application.

We need to take over the loaded event as in this point the treeview finished loading and the items are already in the Items list of the treeview. In the loaded event we will go over all items in the list and find the ones we are looking for. The trick in having the items not selectable is simple: not giving them focus.

So first let's run over the items:

C#
// Here we are setting the "ContainerViewModel" not focusable so we cannot select it.
private void TreeViewLoaded(object sender, RoutedEventArgs routedEventArgs)
{
    foreach (var item in AssociatedObject.Items)
    {
        if (item is ContainerViewModel)
        {
            SetNotFocusable(AssociatedObject, item);
        }
    }
}

The items in the list are of the type I've bound them to (different view models) so I can't really set focusable to false. I need a helper method that will do it for me. The helper method will need to run over the TreeViewItems in the list and find a requested item, and set its focusable property to false.

I got from the web a general method that gets a parent class for items named ItemsControl.

The first thing the method does is try and get the requested item from the ItemsControl children. As it can only get level 1 items, the method is recursive.

C#
static private bool SetNotFocusable(ItemsControl parent, object child)
{
    if (parent == null || child == null)
        return false;

    TreeViewItem childNode = parent.ItemContainerGenerator
        .ContainerFromItem(child) as TreeViewItem;

    if (childNode != null)
    {
   
        return childNode.Focusable = false;
    }
}

We are using above the method ContainerFromItem in order to get the TreeViewItem itself from the object we need, which the TreeViewItem wraps. Once found, we set its Focusable property to false.

If not found then we need to go over the children, and if one of them is a container itself then go inside.

C#
if (parent.Items.Count > 0)
{
    foreach (object childItem in parent.Items)
    {
        ItemsControl childControl = parent
            .ItemContainerGenerator
            .ContainerFromItem(childItem)
            as ItemsControl;

        if (SetNotFocusable(childControl, child))
        {
            return true;
        }
    }
}

If trying to find the object fails then return false.

Here is the complete method:

C#
static private bool SetNotFocusable(ItemsControl parent, object child)
{
    if (parent == null || child == null)
        return false;

    TreeViewItem childNode = parent.ItemContainerGenerator
        .ContainerFromItem(child) as TreeViewItem;

    if (childNode != null)
    {
        childNode.Focus();
        return childNode.Focusable = false;
    }

    if (parent.Items.Count > 0)
    {
        foreach (object childItem in parent.Items)
        {
            ItemsControl childControl = parent
                .ItemContainerGenerator
                .ContainerFromItem(childItem)
                as ItemsControl;

            if (SetNotFocusable(childControl, child))
            {
                return true;
            }
        }
    }

    return false;
}

Hope this will help you as it helped me.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Israel Israel
Just a guy who loves to code, and was fortune enough to also work in coding.

Comments and Discussions

 
-- There are no messages in this forum --