Friday, August 3, 2012

WPF Tree view binding how to stuff.

Introduction

Treeview is a very useful control, yet not that much used in real life scenario, however; it has a very good potential and the control is very customizable. Even though it has some disadvantages over some special category of data but none the less this control is a great addition to WPF default control set. In this particular article we will look at some basic functionality that WPF Tree view can provides, in particular we will take a look at the binding options. 

Basic Uses

Bellow I have given a simple code, that shows how to add a treeview in XAML. The Treeview Items are also defined as as a child nodes.

<Window x:Class="WPFTreeView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TreeView Height="287"
HorizontalAlignment="Left"
Margin="12,12,0,0"
Name="treeView1"
VerticalAlignment="Top"
Width="479">
<TreeViewItem Header="Bing">
<TreeViewItem Header="A" />
<TreeViewItem Header="B" />
<TreeViewItem Header="C" />
</TreeViewItem>
<TreeViewItem Header="Google" >
<TreeViewItem Header="D" />
<TreeViewItem Header="E" />
</TreeViewItem>
<TreeViewItem Header="Yahoo" >
<TreeViewItem Header="F" />
</TreeViewItem>
</TreeView>
</Grid>
</Window>


 

If you want to Populate the tree view and its node from c# code bellow I have listed few line of code to demonstrate how to do that.


using System.Windows;
using System.Windows.Controls;

namespace WPFTreeView
{
public partial class WindowTreeViewFromCodexaml
{
private TreeView _treeView;

public WindowTreeViewFromCodexaml()
{
InitializeComponent();
BuildTreeView();
BuildTreeViewNodes(0,_treeView.Items);
}

private void BuildTreeViewNodes(int level, ItemCollection itemCollection)
{
if(level==3)
return;

for (int i = 0; i < 3; i++)
{
var item = new TreeViewItem();
item.Header = string.Format("Item {0}", i + 1);
BuildTreeViewNodes(level+1,item.Items);
itemCollection.Add(item);
}
}

private void BuildTreeView()
{
TreeViewContainer.Children.Clear();
_treeView = new TreeView();
_treeView.HorizontalAlignment = HorizontalAlignment.Left;
_treeView.Margin = new Thickness(12, 12, 0, 0);
_treeView.Name = "treeView1";
_treeView.VerticalAlignment = VerticalAlignment.Top;
TreeViewContainer.Children.Add(_treeView);
}
}
}


Binding to a source


In this section we would see how we can bind a Treeview to a data source which has a hierarchical structure. For this scenario let’s Consider the following example. “ We want to display employee information as hierarchical data. The corresponding xaml and c# code is given bellow. 


XAML code


<Window x:Class="WPFTreeView.WindowTreeViewWithItemSource"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowTreeViewWithItemSource" Height="300" Width="300">
<Window.Resources>
<HierarchicalDataTemplate x:Key="ItemTemplate" ItemsSource="{Binding Employees}" >
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}"></CheckBox>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<DockPanel LastChildFill="True">
<TreeView
Name="treeView1"
ItemTemplate="{StaticResource ItemTemplate}"
ItemsSource="{Binding Employees}">
</TreeView>
</DockPanel>
</Grid>
</Window>


Above  Xaml code shows declaration of WPF treeview where ItemSource is Employee Dependency Property. But we would assign the item source from code. And this would work perfectly as we override the binding with hard code source. We have also defined a item template for each tree view item node. Bellow the corresponding c# code is given.


C# code


public partial class WindowTreeViewWithItemSource
{
public WindowTreeViewWithItemSource()
{
InitializeComponent();
LoadData();
}

private void LoadData()
{
var employees = new List();
for (int i =1; i <= 100; i++)
{
var manager = new Employee {Name = string.Format("Manager {0}", i.ToString())};
for (int j = 1; j <= 100; j++)
{
var lead = new Employee { Name = string.Format("Team Lead {0}", i.ToString()) };
for (int k = 0; k < 100; k++)
{
var junior = new Employee { Name = string.Format("Developer {0}", i.ToString())};
lead.Employees.Add(junior);
}
manager.Employees.Add(lead);
}
employees.Add(manager);
}
treeView1.ItemsSource = employees;
}
}

public class Employee
{
public Employee()
{
Employees = new List();
}
public string Name { get; set; }
public string Department { get; set; }
public int Age { get; set; }
public string Designation { get; set; }
public string Email { get; set; }
public DateTime DateOfJoin { get; set; }
public double Salary { get; set; }
public List Employees { get; private set; }
}


In above code we have defined a custom user type named “Employee” and constructed a demo hierarchy data, and finally assigned to the item source of the treeview. Note that here we did assigned itemsouce directly. If we want to use binding in that case we have to use mvp (model view presenter) or MVVM ( Model View ViewModel) pattern.


public partial class WindowTreeViewWithItemSourceBinding
{
public WindowTreeViewWithItemSourceBinding()
{
InitializeComponent();
this.DataContext = new TreeViewPresenter();
}
}

public class TreeViewPresenter:DependencyObject
{
public TreeViewPresenter()
{
LoadData();
}
private void LoadData()
{
var employees = new List<Employee>();
for (int i = 1; i <= 100; i++)
{
var manager = new Employee { Name = string.Format("Manager {0}", i.ToString()) };
for (int j = 1; j <= 100; j++)
{
var lead = new Employee { Name = string.Format("Team Lead {0}", i.ToString()) };
for (int k = 0; k < 100; k++)
{
var junior = new Employee { Name =
                    string.Format("Developer {0}", i.ToString()) };
lead.Employees.Add(junior);
}
manager.Employees.Add(lead);
}
employees.Add(manager);
}
Employees = employees;
}
public List<Employee> Employees
{
get { return (List<Employee>)GetValue(EmployeesProperty); }
set { SetValue(EmployeesProperty, value); }
}

public static readonly DependencyProperty EmployeesProperty =
DependencyProperty.Register("Employees", typeof(List<Employee>),
typeof(TreeViewPresenter), new UIPropertyMetadata(null));
}


Summery


In this short article we have seen how to use WPF tree view and some usages of WPF tree view as far as the binding and populating tree view is concern.


References


MSDN Help


No comments:

Post a Comment