29

Ho un po 'di una situazione complessa con Wevf Treeview Binding. Ho trascorso gli ultimi 2 giorni a provare su Google, e this è il problema con cui sono uscito, ma non risolve il problema.WPF Treeview Databinding Hierarchal Dati con tipi misti

Ecco la situazione:

Ho un oggetto che assomiglia a questo:

public class Category 
{ 
    public string Name { get; set; } 
    public List<Category> Categories { get; set; } 
    public List<Product> Products { get; set; } 
} 

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

ogni categoria può avere un elenco di oggetti e categorie bambino. Ho una ragione per farlo che ha perfettamente senso per me e l'app che sto scrivendo.

La costruzione oggetto reale può essere simile a questa:

Category - Pharmacy 
    |-Product - Aspirin 
    |-Product - Tylenol 
    |-Category - Tooth Paste 
    | |-Product - Crest 
    | |-Product - Colgate 
    |-Category - Paper Products 
    |-Category - Toilet Paper 
    | |-Product - NoName 
    | |-Product - Charmin 
    |-Category - Facial Tissue 
     |-Product - Kleenex 
Category - Household 
    |-Product - Pinesol Cleaner 
    |-Product - Garbage Bags 

Ora, sto cercando di DataBind questo rapporto ad un albero. Vorrei che TreeView sembrasse quasi identico al precedente costrutto oggetto.

Finora ho il mio XAML Treeview simile a questa:

<TreeView x:Name="CategoryList" Margin="8" Grid.Row="2" Grid.RowSpan="2" ItemsSource="{Binding Path=Categories}"> 
      <TreeView.Resources> 
       <HierarchicalDataTemplate DataType="{x:Type src:Category}" ItemsSource="{Binding Products}"> 
        <StackPanel> 
         <TextBlock Text="{Binding Path=Name}" /> 
        </StackPanel> 
       </HierarchicalDataTemplate> 
       <HierarchicalDataTemplate DataType="{x:Type src:Product}"> 
        <StackPanel> 
         <TextBlock Text="{Binding Path=Name}" /> 
        </StackPanel> 
       </HierarchicalDataTemplate> 
      </TreeView.Resources> 
     </TreeView> 

Questa grande opera per la lista principale delle categorie, e ciascuno dei suoi prodotti secondari. Ma non va più in profondità e mostra le sottocategorie sotto ogni categoria.

C'è un modo per farlo direttamente con Templates in modo che ogni elemento (categoria o prodotto) sia selezionato? Sto usando un pattern MVVM e non voglio ricorrere all'uso del codice, ma lo sarà se è necessario.

risposta

46

Poiché si desidera che gli elementi di TreeView contengano un elenco di articoli per bambini che comprende entrambi i prodotti di categorie, è necessario che Category ViewModel abbia una raccolta composta da categorie e prodotti. Ad esempio, è possibile utilizzare un CompositeCollection per combinare le vostre collezioni esistenti:

public class Category 
{ 
    public string Name { get; set; } 
    public List<Category> Categories { get; set; } 
    public List<Product> Products { get; set; } 

    public IList Children 
    { 
     get 
     { 
      return new CompositeCollection() 
      { 
       new CollectionContainer() { Collection = Products }, 
       new CollectionContainer() { Collection = Categories } 
      }; 
     } 
    } 
} 

(nel codice vero e proprio, si sarebbe probabilmente vuole mantenere un riferimento allo stesso oggetto di raccolta, piuttosto che crearne uno nuovo ogni volta.)

Poi, nel tuo HierarchicalDataTemplate, utilizzare l'elenco combinato come ItemsSource:

<HierarchicalDataTemplate DataType="{x:Type src:Category}" 
          ItemsSource="{Binding Children}"> 

Gli articoli saranno un mix di prodotto e di categoria di oggetti, e WPF utilizzeranno la DataTemplate appropriata per ciascuno di essi.

+2

Questa è una soluzione perfetta, grazie! Proprio come una nota per chiunque altro, l'ordine in cui aggiungi i contenitori della raccolta alla raccolta composita è l'ordine in cui appaiono nella vista ad albero. Se aggiungi prima le categorie, queste appariranno prima dei prodotti – thorkia