This article has been localized into Portuguese by the community.
TreeView, data binding e múltiplos templates
O WPF TreeView suporta ligação de dados, como praticamente todos os outros controles do WPF, mas como o TreeView é hierárquico por natureza, um DataTemplate normal geralmente não é suficiente. Em vez disso, usamos o HierarchicalDataTemplate, que nos permite modelar o próprio nó da árvore, enquanto controlamos qual propriedade usar como origem para itens filhos do nó.
Um TreeView básico com data binding
No exemplo a seguir, mostrarei como é fácil começar com o HierarchicalDataTemplate:
<Window x:Class="WpfTutorialSamples.TreeView_control.TreeViewDataBindingSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:self="clr-namespace:WpfTutorialSamples.TreeView_control"
Title="TreeViewDataBindingSample" Height="150" Width="200">
<Grid Margin="10">
<TreeView Name="trvMenu">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type self:MenuItem}" ItemsSource="{Binding Items}">
<TextBlock Text="{Binding Title}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.IO;
using System.Collections.ObjectModel;
namespace WpfTutorialSamples.TreeView_control
{
public partial class TreeViewDataBindingSample : Window
{
public TreeViewDataBindingSample()
{
InitializeComponent();
MenuItem root = new MenuItem() { Title = "Menu" };
MenuItem childItem1 = new MenuItem() { Title = "Child item #1" };
childItem1.Items.Add(new MenuItem() { Title = "Child item #1.1" });
childItem1.Items.Add(new MenuItem() { Title = "Child item #1.2" });
root.Items.Add(childItem1);
root.Items.Add(new MenuItem() { Title = "Child item #2" });
trvMenu.Items.Add(root);
}
}
public class MenuItem
{
public MenuItem()
{
this.Items = new ObservableCollection<MenuItem>();
}
public string Title { get; set; }
public ObservableCollection<MenuItem> Items { get; set; }
}
}
Na marcação XAML, especifiquei um HierarchicalDataTemplate para o ItemTemplate do TreeView. Eu o instruo a usar a propriedade Items para encontrar itens filhos, definindo a propriedade ItemsSource do modelo, e dentro dela eu defino o modelo real, que por enquanto apenas consiste em um TextBlock ligado à propriedade Title .
Este primeiro exemplo foi muito simples, de fato tão simples que poderíamos ter apenas adicionado os itens TreeView manualmente, em vez de gerar um conjunto de objetos e então vinculá-los. No entanto, assim que as coisas ficam um pouco mais complicadas, as vantagens de usar ligações de dados ficam mais óbvias.
Vários modelos para diferentes tipos
No próximo exemplo, tomei um caso um pouco mais complexo, no qual quero mostrar uma árvore de famílias e seus membros. Uma família deve ser representada de uma maneira, enquanto cada um de seus membros deve ser mostrado de outra maneira. Conseguirei isso criando dois modelos diferentes e especificando-os como recursos da árvore (ou a Janela ou o Aplicativo - isso é realmente com você) e, em seguida, permitindo que o TreeView escolha o modelo correto com base no tipo de dados subjacente.
Aqui está o código - a explicação dele seguirá logo depois:
<Window x:Class="WpfTutorialSamples.TreeView_control.TreeViewMultipleTemplatesSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:self="clr-namespace:WpfTutorialSamples.TreeView_control"
Title="TreeViewMultipleTemplatesSample" Height="200" Width="250">
<Grid Margin="10">
<TreeView Name="trvFamilies">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type self:Family}" ItemsSource="{Binding Members}">
<StackPanel Orientation="Horizontal">
<Image Source="/WpfTutorialSamples;component/Images/group.png" Margin="0,0,5,0" />
<TextBlock Text="{Binding Name}" />
<TextBlock Text=" [" Foreground="Blue" />
<TextBlock Text="{Binding Members.Count}" Foreground="Blue" />
<TextBlock Text="]" Foreground="Blue" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type self:FamilyMember}">
<StackPanel Orientation="Horizontal">
<Image Source="/WpfTutorialSamples;component/Images/user.png" Margin="0,0,5,0" />
<TextBlock Text="{Binding Name}" />
<TextBlock Text=" (" Foreground="Green" />
<TextBlock Text="{Binding Age}" Foreground="Green" />
<TextBlock Text=" years)" Foreground="Green" />
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Collections.ObjectModel;
namespace WpfTutorialSamples.TreeView_control
{
public partial class TreeViewMultipleTemplatesSample : Window
{
public TreeViewMultipleTemplatesSample()
{
InitializeComponent();
List<Family> families = new List<Family>();
Family family1 = new Family() { Name = "The Doe's" };
family1.Members.Add(new FamilyMember() { Name = "John Doe", Age = 42 });
family1.Members.Add(new FamilyMember() { Name = "Jane Doe", Age = 39 });
family1.Members.Add(new FamilyMember() { Name = "Sammy Doe", Age = 13 });
families.Add(family1);
Family family2 = new Family() { Name = "The Moe's" };
family2.Members.Add(new FamilyMember() { Name = "Mark Moe", Age = 31 });
family2.Members.Add(new FamilyMember() { Name = "Norma Moe", Age = 28 });
families.Add(family2);
trvFamilies.ItemsSource = families;
}
}
public class Family
{
public Family()
{
this.Members = new ObservableCollection<FamilyMember>();
}
public string Name { get; set; }
public ObservableCollection<FamilyMember> Members { get; set; }
}
public class FamilyMember
{
public string Name { get; set; }
public int Age { get; set; }
}
}
Como mencionado, os dois modelos são declarados como parte dos recursos do TreeView, permitindo que o TreeView selecione o modelo apropriado com base no tipo de dados que está prestes a ser exibido. O modelo definido para o tipo Family é um modelo hierárquico, usando a propriedade Members para mostrar seus membros da família.
O modelo definido para o tipo FamilyMember é um DataTemplate regular, pois esse tipo não possui nenhum membro filho. No entanto, se quiséssemos que cada membro da família mantivesse uma coleção de seus filhos e talvez dos filhos de seus filhos, em vez disso, teríamos usado um modelo hierárquico.
Nos dois modelos, usamos uma imagem que representa uma família ou um membro da família, e depois mostramos alguns dados interessantes sobre ela, como a quantidade de membros da família ou a idade da pessoa.
No code-behind, simplesmente criamos duas instâncias Family, preenchemos cada uma delas com um conjunto de membros e, em seguida, adicionamos cada uma das famílias a uma lista, que é então usada como a origem dos itens para o TreeView.
Resumo
Usando a vinculação de dados, o TreeView é muito personalizável e com a capacidade de especificar vários modelos para renderizar diferentes tipos de dados, as possibilidades são quase infinitas.