Modification du modèle d'un TreeViewItem lorsqu'il est sélectionné
-
21-08-2019 - |
Question
Je vais avoir quelques problèmes pour changer le DataTemplate qui est utilisé pour un TreeViewItem lorsqu'il est sélectionné. Idéalement, je voudrais chaque élément pour contenir un TextBlock
, puis lorsqu'il est sélectionné, il doit contenir une place TextBox
.
Voici ce que j'ai jusqu'à présent (je cette question en tant que point de départ):
<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>
Qu'est-ce qui se passe est qu'il n'y a qu'un seul nœud de l'arbre, et le texte du nœud est le nom du type de l'objet. On dirait que le type lié au nœud est pas ce que le modèle attend, donc il utilise la valeur par défaut au lieu de lier ToString()
la propriété que je Text
spécifié.
J'ai mis le DataContext de la fenêtre dans le fichier code-behind. Je sais que mes liaisons pour les données sont correctes, parce que si je mets un pour l'TreeView HierarchicalDataTemplate
les données sont affichées correctement.
Je pense que mon problème est que je dois définir une propriété autre que dans les ItemTemplate
styles TreeViewItem
- j'utilise le droit de propriété, ou devrais-je mettre autre chose
La solution
Il est en fait HeaderTemplate dont vous avez besoin - c'est ce qui gouverne le style du nœud lui-même. Juste donc il y a un échantillon complet, voici ce qui a fonctionné pour moi:
<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>
.. avec un code de test derrière comme ceci:
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