Cambio de la plantilla de un TreeViewItem cuando se selecciona
-
21-08-2019 - |
Pregunta
Estoy teniendo algunos problemas cambiando el DataTemplate que se utiliza para una TreeViewItem cuando se selecciona. Idealmente, me gustaría cada elemento para contener una TextBlock
, y luego, cuando seleccionada debe contener un TextBox
lugar.
Esto es lo que tengo hasta ahora (he usado esta pregunta como punto 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>
Lo que pasa es que sólo hay un nodo en el árbol, y el texto del nodo es el nombre del tipo de objeto. Suena como el tipo con destino al nodo no es lo que la plantilla está a la espera, por lo que se trata de utilizar el valor por defecto ToString()
vinculante en lugar de la Text
propiedad como he especificado.
He puesto el DataContext de la ventana en el código detrás de archivo. Sé que mis enlaces para los datos son correctos, porque si me puse uno HierarchicalDataTemplate
para el TreeView los datos se muestran correctamente.
Creo que mi problema es que tengo que establecer una propiedad que no sea ItemTemplate
en los estilos TreeViewItem
- estoy usando el derecho de propiedad, o debo configurar algo más
Solución
En realidad es la que necesita HeaderTemplate - eso es lo que gobierna el estilo del propio nodo. Justo lo que no es una muestra completa, esto es lo que funcionó para mí:
<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>
.. con un poco de código de prueba detrás de la siguiente manera:
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