Click here to Skip to main content
15,880,608 members
Articles / Programming Languages / C# 4.0

Programmatic Silverlight Tree View Control Node Expansion using View Model (MVVM)

Rate me:
Please Sign up or sign in to vote.
4.98/5 (18 votes)
5 Nov 2010Ms-PL2 min read 112K   2.7K   33   24
Programmatically selecting a Silverlight Tree View Control node using View Model (MVVM)
Image 1

The Silverlight Tree View Control and View Model (MVVM)

Live example: http://silverlight.adefwebserver.com/ViewModelTreeControl

Also see: Silverlight DataTrigger is the Answer to View Model / MVVM issues

When using the Silverlight Tree View Control, you will discover that it is not easy to expand a Tree Node programmatically without using code behind. This article shows how to do that using a Behavior.

Using The Silverlight Tree View Control

Let's look at the normal operation of the Silverlight Tree View Control using View Model (MVVM):

Image 2

We start off with a simple Category class...

Click to enlarge image

We bind a collection of Categories to the Tree View Control.

We create an ICommand that will set the IsSelected property of one of the nodes:

C#
public ICommand SetCategoryCommand { get; set; }
public void SetCategory(object param)
{  
    foreach (var Cat in colCategory)
    {
        // Find the Node
        var result = (from objCategory in Cat.AllChildren()
                        where objCategory.CategoryName == "Category Sub1-1"
                        select objCategory).FirstOrDefault();
                        
        if (result != null)
        {
            // Set the IsSelected property so the checkbox
            // will be checked
            result.IsSelected = true;
        }
    }
}

private bool CanSetCategory(object param)
{
    return true;
}

Image 4

We can then invoke the ICommand with a Button, and the check box on the node is selected.

Image 5

The problem is, if the Silverlight Tree View Control is collapsed, the Node will be checked but you will not know it unless you expand the Tree Node.

Programmatically Selecting The Tree Node

The first step to programmatically selecting the Tree Node is to create a property in the View Model to hold the value of the selected node:

C#
private Category _SelectedCategory;
public Category SelectedCategory
{
    get { return _SelectedCategory; }
    set
    {
        if (SelectedCategory == value)
        {
            return;
        }
        _SelectedCategory = value;
        this.NotifyPropertyChanged("SelectedCategory");
    }
}

And setting the value:

C#
// Set the SelectedCategory property
// so the Behavior will know what node to open
SelectedCategory = objCategorySub0;

Image 6

Next, we create a Behavior and drop it on the Tree View Control.

Image 7

We set the Button to trigger the Behavior, and we bind the SelectedCategory to the Behavior.

Notice, there is also a ExpandOnLoad check box, to allow us to indicate if the node should expand when the page is loaded, or when triggered by an event such as a Button click.

Image 8

When we run the project and click the Button...

Image 9

The Silverlight Tree View Control Node is automatically expanded.

The Behavior

The Behavior does not consist of a lot of code. This is the method that does most of the work:

C#
private void SelectNode()
{
    // Only try to expand Node if the SelectedCategory is set
    if (SelectedCategory != null)
    {
        // Refresh Tree Control
        objTreeView.UpdateLayout();
        // Get the DataContext of the Tree Control
        MainPageViewModel objMainPageViewModel = 
		(MainPageViewModel)objTreeView.DataContext;
        // Get collection of items bound to Tree Control
        ObservableCollection<category> colCategories = 
		(ObservableCollection<category>)objMainPageViewModel.colCategory;
        
        // Loop through the top levels items
        foreach (var Cat in colCategories)
        {
            // Find the Node - Is it a child of this parent?
            var result = (from objCategory in Cat.AllChildren()
                            where objCategory == SelectedCategory
                            select objCategory).FirstOrDefault();
                            
            // If the selected item is a child of the Parent
            if (result != null)
            {
                // Get the Tree Control node container for the item
                TreeViewItem objTreeViewItem = 
		(TreeViewItem)objTreeView.ItemContainerGenerator.ContainerFromItem(Cat);
                // Expand the Node
                objTreeViewItem.IsExpanded = true;
                
                // Refresh Tree Control
                objTreeView.UpdateLayout();
                
                ExpandChildNode(objTreeViewItem, Cat);
            }
        }
    }
}

// This method expands child nodes
private void ExpandChildNode(TreeViewItem objTreeViewItem, Category Cat)
{
    // Loop through all the sub Categories
    foreach (var item in Cat.Categories)
    {
        // Find the Node - Is it a child of this parent?
        var result = (from objCategory in item.AllChildren()
                        where objCategory == SelectedCategory
                        select objCategory).FirstOrDefault();
                        
        // If the selected item is a child of the Parent
        if (result != null)
        {
            // Get the Tree Control node container for the item
            TreeViewItem SubTreeViewItem = (TreeViewItem)
		objTreeViewItem.ItemContainerGenerator.ContainerFromItem(item);
            // Expand the Node
            SubTreeViewItem.IsExpanded = true;
            
            // Refresh Tree Control
            objTreeView.UpdateLayout();
            
            // Recursively call the function                
            ExpandChildNode(SubTreeViewItem, item);
        }
    }
}

What's Wrong With Code Behind?

There are a number of projects that I am working on where we allow a Designer, with no programming ability, to use Microsoft Expression Blend, to create a UI for a Silverlight Application. For this reason, we do not want to use any code behind, because the Designer would need to know how to program to avoid breaking something.

When we are able to implement Silverlight project with no code behind, we do not have this problem.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Software Developer (Senior) http://ADefWebserver.com
United States United States
Michael Washington is a Microsoft MVP. He is a ASP.NET and
C# programmer.
He is the founder of
AiHelpWebsite.com,
LightSwitchHelpWebsite.com, and
HoloLensHelpWebsite.com.

He has a son, Zachary and resides in Los Angeles with his wife Valerie.

He is the Author of:

Comments and Discussions

 
QuestionError 2 The type or namespace name 'TargetedTriggerAction' could not be found Pin
Roger C Moore23-Mar-12 8:09
Roger C Moore23-Mar-12 8:09 
AnswerRe: Error 2 The type or namespace name 'TargetedTriggerAction' could not be found Pin
Roger C Moore23-Mar-12 8:10
Roger C Moore23-Mar-12 8:10 
GeneralRe: Error 2 The type or namespace name 'TargetedTriggerAction' could not be found Pin
defwebserver23-Mar-12 8:29
defwebserver23-Mar-12 8:29 
GeneralMy vote of 4 Pin
Albert van Peppen4-Mar-12 22:33
professionalAlbert van Peppen4-Mar-12 22:33 
Questionhow i expend the tree onload event Pin
etty cohen5-Sep-11 20:08
etty cohen5-Sep-11 20:08 
Questionexpanding using code behind Pin
Member 804595015-Aug-11 3:45
Member 804595015-Aug-11 3:45 
AnswerRe: expanding using code behind Pin
defwebserver15-Aug-11 4:03
defwebserver15-Aug-11 4:03 
GeneralMy vote of 5 Pin
Member 40413413-Mar-11 22:26
Member 40413413-Mar-11 22:26 
GeneralRe: My vote of 5 Pin
defwebserver15-Aug-11 11:28
defwebserver15-Aug-11 11:28 
GeneralMy vote of 5 Pin
Katka Vaughan9-Nov-10 22:54
Katka Vaughan9-Nov-10 22:54 
GeneralRe: My vote of 5 Pin
defwebserver15-Nov-10 4:05
defwebserver15-Nov-10 4:05 
GeneralMy vote of 5 Pin
Mamta D9-Nov-10 0:32
Mamta D9-Nov-10 0:32 
GeneralRe: My vote of 5 Pin
defwebserver15-Nov-10 4:05
defwebserver15-Nov-10 4:05 
GeneralGreat job Michael Pin
Pete O'Hanlon28-Oct-10 12:27
mvePete O'Hanlon28-Oct-10 12:27 
GeneralRe: Great job Michael Pin
defwebserver28-Oct-10 12:29
defwebserver28-Oct-10 12:29 
GeneralRe: Great job Michael Pin
shakil03040037-Nov-10 3:22
shakil03040037-Nov-10 3:22 
GeneralRe: Great job Michael Pin
defwebserver7-Nov-10 3:50
defwebserver7-Nov-10 3:50 
GeneralMy vote of 5 Pin
linuxjr28-Oct-10 2:30
professionallinuxjr28-Oct-10 2:30 
GeneralRe: My vote of 5 Pin
defwebserver30-Oct-10 7:39
defwebserver30-Oct-10 7:39 
GeneralColor Scheme, etc. Pin
Dewey22-Oct-10 13:18
Dewey22-Oct-10 13:18 
GeneralRe: Color Scheme, etc. Pin
defwebserver22-Oct-10 13:46
defwebserver22-Oct-10 13:46 
Hey Thanks for the vote and the comments.

However, all credit goes to the Microsoft team that created the "JetPack" Silverlight Theme:
http://timheuer.com/blog/archive/2010/09/09/silverlight-jetpack-theme-released.aspx
GeneralNice, you may also want to check Joshs master piece out too [modified] Pin
Sacha Barber22-Oct-10 2:23
Sacha Barber22-Oct-10 2:23 
GeneralRe: Nice, you may also want to check Joshs master piece out too Pin
defwebserver22-Oct-10 2:45
defwebserver22-Oct-10 2:45 
GeneralRe: Nice, you may also want to check Joshs master piece out too Pin
Sacha Barber22-Oct-10 5:06
Sacha Barber22-Oct-10 5:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.