2015-06-24 52 views
0

我有一個看起來像這樣的產品的平面文件:搞清楚4級樹視圖項綁定在WPF

public List<Product> Products = new List<Product>{ 
new Product{Name = "OIS Swap", AssetType="Rates",ProductType="Swap",Currency="USD"}, 
new Product{Name = "Libor Swap", AssetType ="Rates",ProductType="Swap",Currency="USD"},}; 

我想通過分類這樣來填充在WPF中的TreeView:

USD 
--Rates 
----Swap 
------OIS Swap 

首先,我已生成使用LINQ這樣的4級層次:

class HierarchyViewModel{ 
    public static IEnumerable<CurrencyViewModel> Currency {get;set;} 
     public HierarchyViewModel() 
     { 
      Currency = Products 
       .OrderBy(prod => prod.Currency) 
       .GroupBy(prod => prod.Currency) 
       .OrderBy(group=> group.Key) 
       .Select(group => 
        new CurrencyViewModel(group.Key, group.Select(prod => prod).ToArray() 
         ) 
         ).ToArray(); 

     } 
    } 

    class CurrencyViewModel 
    { 
     public string currency; 
     public IEnumerable<AssetTypeViewModel> AssetTypes { get; set; } 

     public CurrencyViewModel(string currency, IEnumerable<Product> CurrencySorted) 
     { 
      this.currency = currency; 
      AssetTypes = CurrencySorted 
         .OrderBy(prod => prod.AssetType) 
         .GroupBy(prod => prod.AssetType) 
         .OrderBy(group => group.Key) 
         .Select(group => new AssetTypeViewModel(group.Key, group.Select(prod => prod).ToArray() 
          ) 
          ).ToArray(); 
     } 
    } 


    class AssetTypeViewModel 
    { 
     public string assettype; 

     public IEnumerable<ProductTypeViewModel> ProductType { get; set; } 

     public AssetTypeViewModel(string assettype, IEnumerable<Product> AssetSorted) 
     { 
      this.assettype = assettype; 
      ProductType = AssetSorted 
       .OrderBy(prod => prod.ProductType) 
       .GroupBy(prod => prod.ProductType) 
       .OrderBy(group => group.Key) 
       .Select(group => new ProductTypeViewModel(group.Key, group.Select(prod => prod).ToArray() 
        ) 
        ).ToArray(); 
     } 

    } 

    class ProductTypeViewModel 
    { 
     string producttype; 
     public IEnumerable<Product> Products; 
     public ProductTypeViewModel(string producttype,IEnumerable<Product> ProductSorted) 
     { 
      this.producttype = producttype; 
      Products = ProductSorted 
       .OrderBy(prod => prod.ProductType) 
       .Select(prod => prod).ToArray(); 
     } 
    } 

在我的XAML,我做的賓迪NGS像這樣:

 <TreeView.Resources> 
      <HierarchicalDataTemplate DataType="{x:Type xy:CurrencyViewModel}" ItemsSource="{Binding currency}"> 
      <TextBlock Text="{Binding currency}"/> 
      </HierarchicalDataTemplate> 
      <HierarchicalDataTemplate DataType="{x:Type xy:AssetTypeViewModel}" ItemsSource="{Binding assettype}"> 
       <TextBlock Text="{Binding assettype}"/> 
      </HierarchicalDataTemplate> 

      <HierarchicalDataTemplate DataType="{x:Type xy:ProductTypeViewModel}" ItemsSource="{Binding producttype}"> 
       <TextBlock Text="{Binding producttype}"/> 
      </HierarchicalDataTemplate> 
      <DataTemplate DataType="{x:Type xy:Product}" > 
       <TextBlock Text="{Binding Name}"/> 
      </DataTemplate> 

     </TreeView.Resources> 

    </TreeView> 

代碼隱藏了我的用戶是

public GraphTreeView() 
     { 
      InitializeComponent(); 


      MyTree.DataContext = new HierarchyViewModel(); 
     } 

但由於某些原因,樹形視圖不填充。我測試了Hierachy一代,它似乎按預期工作。我確信我的綁定中有一些錯誤,我希望你能幫忙解決這個問題。 在此先感謝!

更新:使用Xavier的回答,我是能夠深入到: 美元 ---價格 ----交換 最後水平仍下落不明。

更新2經過一番爭吵,並使用Snoop檢查它的綁定方式後,我'入侵'了答案。事實證明,綁定(按照預期)吐出了一個沒有ToString()方法定義的'Product'類的列表。我覆蓋了我的班級定義中的那些,並使用ItemContainerStyle作爲資源來定義最後一段綁定。如果有人感興趣,這裏是完整的XAML。非常感謝Xavier讓我走上了正確的道路。

<UserControl.Resources> 
     <xy:ProducttoNameConverter x:Key="ProductToNameConverter"/> 
     <ItemContainerTemplate x:Key="LastLegConverter">   

      <TextBlock Text="{Binding}"/> 

     </ItemContainerTemplate> 

    </UserControl.Resources> 
<TreeView x:Name="MyTree" ItemsSource="{Binding Currency}"> 

      <TreeView.Resources> 
       <HierarchicalDataTemplate DataType="{x:Type xy:CurrencyViewModel}" ItemsSource="{Binding AssetTypes }" > 

        <TextBlock Text="{Binding MyCurrency}"/> 
       </HierarchicalDataTemplate> 

       <HierarchicalDataTemplate DataType="{x:Type xy:AssetTypeViewModel}" ItemsSource="{Binding ProductType}"> 

        <TextBlock Text="{Binding MyAssetType}"/> 

       </HierarchicalDataTemplate> 
       <HierarchicalDataTemplate DataType="{x:Type xy:ProductTypeViewModel}" ItemTemplate="{StaticResource LastLegConverter}" ItemsSource="{Binding Products}"> 
        <TextBlock Text="{Binding MyProductType}"/> 


       </HierarchicalDataTemplate> 

       </TreeView.Resources> 

回答

0

確保您在TreeView本身ItemsSource設置到最外面的集合。此外,您需要將每個數據模板上的ItemsSource屬性設置爲關聯視圖模型中的子集合。

例如:

<TreeView ItemsSource="{Binding Currency}"> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type xy:CurrencyViewModel}" ItemsSource="{Binding AssetTypes}"> 
      <TextBlock Text="{Binding currency}"/> 
     </HierarchicalDataTemplate> 
     ... 
    </TreeView.Resources> 
</TreeView> 

設置在TreeViewItemsSource獲取過程開始用於填充控制,那麼在集散控制項中定義的數據模板如何每個項目提出。

HiearchicalDataTemplate的目的是通知每個子視圖在哪裏找到該類型的每個項目的子項目。因此,每個TreeViewItem將使用關聯模板的內容來構建其視圖,並使用ItemsSource屬性查找要爲其創建其自己的子視圖的項目集合。該過程繼續,直到整個樹生成。

+0

謝謝,它似乎在前三個級別上工作,但最後一級是我面臨問題的地方。我在最後一個HierarchicalDataTemplate中指定了一個Itemtemplate。然後設置一個帶有Itemource IEnumerable 產品的DataTemplate,以顯示帶有Product.Name的TextBox。它拒絕深入研究。你會碰巧知道這是爲什麼嗎? –

+0

嗯,它是因爲最後一個分層數據模板,即ProductTypeViewModel沒有子元素。但它確實有我想要提取的產品列表。 –