Alterar o modelo de um TreeViewItem quando ele é selecionado
-
21-08-2019 - |
Pergunta
Eu estou tendo alguns problemas alterando o DataTemplate que é usado para um TreeViewItem quando ele é selecionado. Idealmente, eu gostaria de cada item para conter uma TextBlock
, e depois quando selecionado deve conter uma TextBox
vez.
Aqui está o que eu tenho até agora (eu usei esta questão como um ponto de partida):
<Window>
<Window.Resources>
<HierarchicalDataTemplate x:Key="normal"
ItemsSource="{Binding Path=Children}">
<TextBlock Text="{Binding Path=Text}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="selected"
ItemsSource="{Binding Path=Children}">
<TextBox Text="{Binding Path=Text}" />
</HierarchicalDataTemplate>
<Style TargetType="{x:Type TreeViewItem}" x:Key="ContainerStyle">
<Setter Property="ItemTemplate" Value="{StaticResource normal}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ItemTemplate" Value="{StaticResource selected}" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resource>
<Grid>
<TreeView ItemSource="{Binding Body}" ItemContainerStyle="{StaticResource ContainerStyle}" />
</Grid>
</Window>
O que acontece é que há apenas um nó na árvore, eo texto do nó é o nome do tipo do objeto. Parece que o tipo ligado ao nó não é o que a modelo está esperando, por isso é usando a ligação em vez da propriedade ToString()
como eu especificado Text
padrão.
Tenho posto o DataContext da janela no código por trás do arquivo. Eu sei que minhas ligações para os dados estão corretos, porque se eu definir um HierarchicalDataTemplate
para o TreeView os dados são exibidos corretamente.
Eu acho que o meu problema é que eu preciso para definir uma propriedade que não seja ItemTemplate
nos estilos TreeViewItem
- estou a utilizar o direito de propriedade, ou devo definir algo mais
Solução
É realmente o HeaderTemplate você precisa - é o que governa o estilo do próprio nó. Apenas para que haja uma amostra completa, isto é o que funcionou para mim:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<HierarchicalDataTemplate x:Key="normal"
ItemsSource="{Binding Path=Children}">
<TextBlock Text="{Binding Path=Text}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="selected"
ItemsSource="{Binding Path=Children}">
<TextBox Text="{Binding Path=Text}" />
</HierarchicalDataTemplate>
<Style TargetType="{x:Type TreeViewItem}"
x:Key="ContainerStyle">
<Setter Property="HeaderTemplate"
Value="{StaticResource normal}" />
<Style.Triggers>
<Trigger Property="IsSelected"
Value="True">
<Setter Property="HeaderTemplate"
Value="{StaticResource selected}" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<TreeView x:Name="_Tree" ItemContainerStyle="{StaticResource ContainerStyle}"/>
</Grid>
</Window>
.. com algum código de teste para trás como este:
Imports System.Collections.ObjectModel
Class Window1
Private Sub Window1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
Dim Root As New Node
Root.Text = "Root"
Dim Child As New Node
Child.Text = "Child"
Root.Children.Add(Child)
Dim Nodes As New Collection(Of Node)
Nodes.Add(Root)
_tree.itemssource = Nodes
End Sub
End Class
Public Class Node
Private _Text As String
Public Property Text() As String
Get
Return _Text
End Get
Set(ByVal Value As String)
_Text = Value
End Set
End Property
Private _Children As New Collection(Of Node)
Public Property Children() As Collection(of node)
Get
Return _Children
End Get
Set(ByVal Value As Collection(of node))
_Children = Value
End Set
End Property
End Class