2009-04-05 4 views
5

Pour enregistrer un objet (par exemple, une instance d'une classe) dans un TreeViewItem, je stocke actuellement l'objet dans le Header de TreeViewItem puis redéfinissant la méthode ToString de cette classe , de sorte qu'il affiche l'en-tête de chaîne correcte; Je rejette ensuite l'objet lors d'un événement. Est-ce la bonne façon de réaliser ce genre de chose, ou y a-t-il un moyen plus approprié?WPF: Correctement le stockage d'un objet dans un TreeViewItem

Répondre

7

La façon "correcte" est d'ajouter juste le object aux TreeView '(s ou TreeViewItem) s' Items collection et utiliser un HierarchicalDataTemplate pour contrôler la façon dont l'élément est rendu:

Person.cs:

public class Person 
{ 
    private readonly ICollection<Person> _children = new ObservableCollection<Person>(); 

    public string Name { get; set; } 

    public ICollection<Person> Children 
    { 
     get 
     { 
      return _children; 
     } 
    } 
} 

Window1.xaml.cs:

public Window1() 
{ 
    InitializeComponent(); 

    var people = new List<Person>(); 
    var kent = new Person() { Name = "Kent" }; 
    kent.Children.Add(new Person() { Name = "Tempany" }); 
    people.Add(kent); 
    _treeView.ItemsSource = people; 
} 

Window1.xaml:

<TreeView x:Name="_treeView"> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type local:Person}" ItemsSource="{Binding Children}"> 
      <TextBlock Text="{Binding Name}"/> 
     </HierarchicalDataTemplate> 
    </TreeView.Resources> 
</TreeView> 
+0

Merci pour la réponse. Comment mettre en œuvre un "HierarchicalDataTemplate imbriqué" pour ainsi dire? Par exemple, les éléments de la liaison ItemsSource ont une autre liste à l'intérieur d'eux, et je veux que la liste soit une sous-liste de ceux-ci. –

+0

np Dreas. Pouvez-vous marquer comme réponse et poser une question distincte sur les HierarchicalDataTemplates imbriqués? –

+0

Salut Kent, fera l'affaire. –

1

La « réponse » ci-dessus à mon avis ne répond pas à la question réelle, et en fait la question initiale indique que l'auteur de la question avait déjà une solution très efficace pour la problème. Cependant, la "réponse" fournie montre simplement comment attacher un sous-objet à un TreeViewItem et comment le rendre ensuite en utilisant une méthode personnalisée. Bien que cela soit utile, cette réponse n'aborde pas la nature réelle de la question initiale.

Il existe de nombreux scénarios dans lesquels TreeViewItem doit être associé à un objet externe qui n'appartient pas à la liste Items de TreeViewItem. Cela facilite l'accès à l'objet externe attaché à des fins spécifiques à l'application lorsque l'utilisateur sélectionne TreeViewItem à partir de TreeView. Ce concept est entièrement différent de l'idée d'ajouter des sous-objets à un TreeViewItem.

Une autre méthode de résolution de ce problème, par opposition à la solution initialement mise en œuvre par l'auteur de la question, consiste à sous-classer la classe TreeViewItem et à ajouter des informations personnalisées, telles qu'un objet joint. Ce principe est illustré dans l'article http://msdn.microsoft.com/en-us/library/1330h6a4.aspx. Après l'implémentation de cette sous-classe TreeViewItem personnalisée, cette sous-classe peut être ajoutée à la liste Items d'un TreeView ou d'un TreeViewItem. Lorsque l'utilisateur sélectionne l'élément dans TreeView, l'objet renvoyé à partir de la sélection sera la sous-classe personnalisée, qui contiendra toutes les informations personnalisées définies par la sous-classe.

Un avantage supplémentaire de l'utilisation d'une sous-classe TreeViewItem personnalisée au lieu d'un TreeViewItem est que les comportements personnalisés peuvent être implémentés par la sous-classe. Par exemple, pour afficher une info-bulle personnalisé lorsque l'utilisateur passe la souris sur l'élément, la sous-classe peut définir un objet infobulle pour lui-même avec le code comme:

ToolTip tip = new ToolTip() { Content = "Tooltip display value" }; 
ToolTipService.SetToolTip(this, tip); 
Questions connexes