29

我對WPF Treeview綁定有點複雜的情況。我花了最後2天嘗試谷歌它,並且this是封閉的我想出了,但它不能解決問題。WPF Treeview數據綁定混合類型的分層數據

這裏的情況是:

我有一個對象,看起來像這樣:

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; 
} 

每個類別可以有對象,類別和子類別的列表。我有一個這樣做的理由,這對我和我正在編寫的應用程序完全有意義。

實際的對象結構可以是這個樣子:

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 

現在,我想這個數據綁定關係,一個TreeView。我希望TreeView看起來幾乎與上面的對象結構相同。

到目前爲止,我有我的XAML樹形像這樣:

<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> 

這對於分類的主列表的偉大工程,每一個它的子產品。但它不會更深入,並顯示每個類別下的子類別。

有沒有什麼辦法可以直接使用模板做到這一點,以便每個項目(類別或產品)被選中?我正在使用MVVM模式,不想訴諸使用後面的代碼,但如果有必要的話。

回答

46

由於您希望TreeView中的元素具有由兩個Categories產品組成的子項列表,因此您希望Category ViewModel具有一個由類別和產品組成的集合。例如,你可以使用一個CompositeCollection到現有集組合:

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 } 
      }; 
     } 
    } 
} 

(在實際的代碼,你可能會想保持相同的集合對象的引用而不是創建一個新的每次。)

然後在你的HierarchicalDataTemplate,使用組合列表作爲的ItemsSource:

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

的項目將是產品和類別對象的混合,而WPF將使用相應的DataTemplate中的每一個。

+2

這是一個完美的解決方案,謝謝!就像其他人的說明一樣,將集合容器添加到組合集合的順序是它們在樹形視圖中顯示的順序。如果您先添加類別,它們會出現在產品之前 – thorkia 2010-09-09 13:54:34