2013-03-06 12 views
13

Per la mia vista ad albero ho due classi diverse che forniscono la risorsa ItemsSource.TreeView, HierarchicalDataTemplate e dati ricorsivi

public class TreeViewModel : ViewModelBase 
{ 
    public ObservableCollection<NodeViewModel> Items { get; set; } 
} 

public class NodeViewModel : ViewModelBase 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public ObservableCollection<NodeViewModel> Children { get; set; } 
} 

Ora voglio la mia TreeView per visualizzare i prodotti in TreeViewModel e mostrare i dati gerarchici forniti dal NodeViewModel.

Ecco il mio XAML

<Window x:Class="TreeViewMasterDetails.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:TreeViewMasterDetails" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <TreeView Height="Auto" 
        HorizontalAlignment="Stretch" 
        Margin="10" 
        VerticalAlignment="Stretch" 
        Width="Auto"> 
      <TreeView.Resources> 
       <HierarchicalDataTemplate DataType="x:Type local:TreeViewModel" ItemsSource="{Binding Items}"> 
        <TextBlock Text="{Binding Path=Name}"></TextBlock> 
       </HierarchicalDataTemplate> 
       <HierarchicalDataTemplate DataType="x:Type local:NodeViewModel" ItemsSource="{Binding Children}"> 
        <TextBlock Text="{Binding Name}"></TextBlock> 
       </HierarchicalDataTemplate> 
      </TreeView.Resources> 
     </TreeView> 
    </Grid> 
</Window> 

cercato di fornire Items come ItemsSource del TreeView. Non mostra i dati gerarchicamente, se mostra qualcosa.

E ho provato a utilizzare lo ItemTemplate anziché lo TreeView.Resources.

Cosa c'è di sbagliato in proposito?

Forse un problema è il primo TextBlock Text Binding? Desidero visualizzare la proprietà Name dello NodeViewModel in Items.

+0

Penso che questo sia un duplicato di [WPF TreeView HierarchicalDataTemplate - binding to object with multiple child collections] [1]. [1]: http://stackoverflow.com/questions/1912481/wpf-treeview-hierarchicaldatatemplate-binding-to-object-with-multiple-child-co – Schollii

+0

Sì, ho già visto. Ma non funziona qui. –

+0

Si prega di vedere la mia domanda aggiornato –

risposta

3

Come @ sa_ddam213 Detto questo, è necessario solo il HierarchicalDataTemplate per NodeViewModel, ma l'unico problema con il codice è stato le parentesi mancanti ({ e }) per DataType="x:Type local:TreeViewModel" nella vostra definizioni dei modelli di dati (dovrebbe essere DataType="{x:Type local:TreeViewModel}"). L'aggiunta di parentesi e il binding ItemsSource risolve il problema:

L'ulteriore HierarchicalDataTemplate per TreeViewModel non viene utilizzato, ma non danneggia.

+0

Hai ragione, questo è davvero il problema. Stranamente, funziona senza le parentesi quando viene usato in 'ItemTemplate', ma non in' Risorse'. –

+0

@MareInfinitus È perché quando viene utilizzato int 'ItemTemplate', non è necessario visualizzare la proprietà' DataType'. Stai dicendo direttamente al 'TreeView' di usare il modello dato per gli oggetti. Quindi non c'è bisogno di 'DataType'. –

23

Si dovrebbe avere solo per dichiarare la HierarchicalDataTemplate per NodeViewModel come questo è l'unica cosa che mostra nel TreeView, e associare l'attuale ItemSource al TreeView

<TreeView ItemsSource="{Binding Items}"> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type local:NodeViewModel}" ItemsSource="{Binding Children}"> 
      <TextBlock Text="{Binding Name}"></TextBlock> 
     </HierarchicalDataTemplate> 
    </TreeView.Resources> 
</TreeView> 

completa Esempio

Xaml:

<Window x:Class="WpfApplication13.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication13" 
     Title="MainWindow" x:Name="UI" Width="343" Height="744.625" > 

    <TreeView DataContext="{Binding ElementName=UI, Path=TreeModel}" ItemsSource="{Binding Items}"> 
     <TreeView.Resources> 
      <HierarchicalDataTemplate DataType="{x:Type local:NodeViewModel}" ItemsSource="{Binding Children}"> 
       <TextBlock Text="{Binding Name}"></TextBlock> 
      </HierarchicalDataTemplate> 
     </TreeView.Resources> 
    </TreeView> 

</Window> 

Codice:

public partial class MainWindow : Window 
{ 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    public TreeViewModel TreeModel 
    { 
     get 
     { 
      return new TreeViewModel 
      { 
       Items = new ObservableCollection<NodeViewModel>{ 
          new NodeViewModel { Name = "Root", Children = new ObservableCollection<NodeViewModel> { 
           new NodeViewModel { Name = "Level1" , Children = new ObservableCollection<NodeViewModel>{ 
            new NodeViewModel{ Name = "Level2"}}} } }} 
      }; 
     } 
    } 
} 

public class TreeViewModel 
{ 
    public ObservableCollection<NodeViewModel> Items { get; set; } 
} 

public class NodeViewModel 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public ObservableCollection<NodeViewModel> Children { get; set; } 
} 

Risultato:

enter image description here

+0

Sì, funziona. Ero sicuro di averlo provato prima. Grazie mille! –

+0

Ciao, grazie per aver condiviso, ho usato la tua soluzione, tuttavia non sembra permettermi di selezionare nulla e anche le frecce a sinistra mancano.L'albero sembra congelato. Una modifica che ho fatto al tuo codice, lego il mio TreeModel dalla mia classe ViewModel non da MainWindow. –

+0

ha funzionato bene per me. Vedi anche https://stackoverflow.com/questions/2251260/ se vuoi che i CheckBox si propagino invece di TextBlocks. – Chris

Problemi correlati