2010-05-20 10 views
3

Je voudrais savoir comment lier un type de données personnalisé à TreeView.Objet lié à WPF TreeView

Le type de données est fondamentalement une liste d'objets contenant d'autres listes de choix. L'accès ressemblerait à quelque chose comme ceci:

foreach (DeviceGroup dg in system.deviceGroups) 
    { 
     foreach (DeviceType dt in dg.deviceTypes) 
     { 
      foreach (DeviceInstance di in dt.deviceInstances) 
      { 

      } 
     } 
    } 

Je voudrais que le TreeView à ressembler à quelque chose comme ceci:

DeviceGroup1

--> DeviceType1 
     --DeviceInstance1 
     --DeviceInstance2 
--> DeviceType2 
     --DeviceInstance1 

DeviceGroup2

--> DeviceType1 
     --DeviceInstance1 
--> DeviceType2 

Répondre

7

Ok c'est là que HierarchicalDataTemplate vous économisera. L'astuce est que vous devrez utiliser deux modèles hiérarchiques différents, puisque vous avez une hiérarchie à trois niveaux ici. J'ai construit un simple UserControl pour illustrer. Tout d'abord, voici quelques données de modèle créateur derrière un code similaire à ce que vous avez:

public partial class ThreeLevelTreeView : UserControl 
{ 
    public ArrayList DeviceGroups { get; private set; } 

    public ThreeLevelTreeView() 
    { 
     DeviceInstance inst1 = new DeviceInstance() { Name = "Instance1" }; 
     DeviceInstance inst2 = new DeviceInstance() { Name = "Instance2" }; 
     DeviceInstance inst3 = new DeviceInstance() { Name = "Instance3" }; 
     DeviceInstance inst4 = new DeviceInstance() { Name = "Instance4" }; 

     DeviceType type1 = new DeviceType() { Name = "Type1", DeviceInstances = new ArrayList() { inst1, inst2 } }; 
     DeviceType type2 = new DeviceType() { Name = "Type2", DeviceInstances = new ArrayList() { inst3 } }; 
     DeviceType type3 = new DeviceType() { Name = "Type3", DeviceInstances = new ArrayList() { inst4 } }; 
     DeviceType type4 = new DeviceType() { Name = "Type4" }; 

     DeviceGroup group1 = new DeviceGroup() { Name = "Group1", DeviceTypes = new ArrayList() { type1, type2 } }; 
     DeviceGroup group2 = new DeviceGroup() { Name = "Group2", DeviceTypes = new ArrayList() { type3, type4 } }; 

     DeviceGroups = new ArrayList() { group1, group2 }; 

     InitializeComponent(); 
    } 
} 

public class DeviceGroup 
{ 
    public string Name { get; set; } 
    public ArrayList DeviceTypes { get; set; } 
} 

public class DeviceType 
{ 
    public string Name { get; set; } 
    public ArrayList DeviceInstances { get; set; } 
} 

public class DeviceInstance 
{ 
    public string Name { get; set; } 
} 

Rien difficile, mais sachez que vous devez utiliser ObservableCollection au lieu de ArrayList si vous voulez ajouter et supprimer de vos collections dynamiquement. Maintenant, nous regardons le XAML pour ce contrôle:

<UserControl x:Class="TestWpfApplication.ThreeLevelTreeView" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:TestWpfApplication" 
DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
<TreeView ItemsSource="{Binding DeviceGroups}"> 
    <TreeView.ItemTemplate> 
     <HierarchicalDataTemplate ItemsSource="{Binding DeviceTypes}"> 
      <HierarchicalDataTemplate.ItemTemplate> 
       <HierarchicalDataTemplate ItemsSource="{Binding DeviceInstances}"> 
        <TextBlock Text="{Binding Name}"/> 
       </HierarchicalDataTemplate> 
      </HierarchicalDataTemplate.ItemTemplate> 
      <TextBlock Text="{Binding Name}"/> 
     </HierarchicalDataTemplate> 
    </TreeView.ItemTemplate> 
</TreeView> 

Et voici le résultat:

alt text http://img684.imageshack.us/img684/6281/threeleveltreeview.png

+0

Merci beaucoup pour votre réponse. Votre exemple fonctionne très bien lorsque la classe est contenue dans ThreeLevelTreeView, mais j'ai quelques difficultés à comprendre comment lier une classe externe au datacontext de ThreeLevelTreeView. Comment ferais-je cela? – Robert

+0

Vous n'êtes pas obligé de lier le DataContext. Vous pourriez simplement le mettre dans le code comme ceci: yourTreeView.DataContext = yourClass. – Charlie

+0

Je me demandais comment lier des données à l'arborescence sans utiliser le contrôle de l'utilisateur. Je dois rediriger tous les gestionnaires d'événements à travers le contrôle de l'utilisateur et je trouve ce genre de fastidieux. J'ai copié la partie TreeView du contrôle utilisateur et l'ai placé dans mon MainWindow.xaml. Je lie les données dans l'événement Window_Loaded comme ceci: _systemTreeView.DataContext = DeviceGroups; Mais rien n'apparaît dans TreeView. – Robert