2015-09-16 27 views
6

我有一個TreeView,看起來像這樣:什麼是具有CollectionViewGroup分組的慣用XAML TreeView?

<TreeView Grid.Row="1" x:Name="InspectionResultsTreeView" 
      ItemsSource="{Binding Source={StaticResource InspectionTypeGroupViewSource}, Path=Groups}" 
      ItemTemplate="{StaticResource InspectionTypeGroupsTemplate}"> 
</TreeView> 

ItemsSource是有鎖的資源,通過InspectionTypeGroupViewSource名雲:

<CollectionViewSource x:Key="InspectionTypeGroupViewSource" Source="{Binding Results}"> 
    <CollectionViewSource.GroupDescriptions> 
     <PropertyGroupDescription PropertyName="Inspection.InspectionType" /> 
     <PropertyGroupDescription PropertyName="Inspection" /> 
    </CollectionViewSource.GroupDescriptions> 
</CollectionViewSource> 

的這個小東西的作用是把視圖模型的Results財產:

private ObservableCollection<ICodeInspectionResult> _results; 

public ObservableCollection<ICodeInspectionResult> Results 
{ 
    get { return _results; } 
    set { _results = value; OnPropertyChanged(); } 
} 

...並將它分爲兩​​個級別 - 第一個通過InspectionType,然後通過Inspection - 結果是具有檢查類型,檢查和單獨檢查結果的3級層次結構。在這一點上的截圖可以幫助可視化我想:

Rubberduck 2.0 Code Inspections toolwindow

因此,InspectionResultsTreeViewItemTemplate是另一個鍵的資源,通過InspectionTypeGroupsTemplate的名字 - 這是大膽「檢查型」項目:

<HierarchicalDataTemplate x:Key="InspectionTypeGroupsTemplate" 
          DataType="{x:Type CollectionViewGroup}" 
          ItemsSource="{Binding Items}" 
          ItemTemplate="{StaticResource InspectionGroupsTemplate}"> 

    <StackPanel Orientation="Horizontal"> 
     <TextBlock VerticalAlignment="Center" 
        Text="{Binding Name}" 
        FontWeight="Bold" 
        TextWrapping="NoWrap"/> 
     <TextBlock Margin="4,0,4,0" 
        VerticalAlignment="Center" 
        Text="{Binding ItemCount, StringFormat=({0})}" 
        TextWrapping="NoWrap"/> 
    </StackPanel> 
</HierarchicalDataTemplate> 

而且該模板的ItemTemplate是一個InspectionGroupsTemplate - 這是個人的檢查,用「嚴重」圖標:

<HierarchicalDataTemplate x:Key="InspectionGroupsTemplate" 
          DataType="{x:Type CollectionViewGroup}" 
          ItemsSource="{Binding Items}" 
          ItemTemplate="{StaticResource InspectionResultTemplate}"> 

    <StackPanel Orientation="Horizontal"> 
     <Image Style="{StaticResource IconStyle}" 
       Source="{Binding Name, Converter={StaticResource InspectionIconConverter}}" 
       VerticalAlignment="Center" /> 
     <TextBlock Margin="4" 
        VerticalAlignment="Center" 
        Text="{Binding Name, Converter={StaticResource InspectionDescriptionConverter}}" 
        TextWrapping="NoWrap"/> 
     <TextBlock Margin="0,4,0,4" 
        VerticalAlignment="Center" 
        Text="{Binding ItemCount, StringFormat=({0})}" 
        TextWrapping="NoWrap"/> 
    </StackPanel> 
</HierarchicalDataTemplate> 

最後,這個分組的ItemTemplateInspectionResultTemplate,這對每個人檢查結果:

<DataTemplate x:Key="InspectionResultTemplate" 
       DataType="{x:Type inspections:ICodeInspectionResult}"> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock VerticalAlignment="Center" 
        Margin="4" 
        Text="{Binding Name}" 
        TextWrapping="NoWrap"/> 
    </StackPanel> 
</DataTemplate> 

ICodeInspectionResult接口有,我使用這裏string Name財產;這Name是不同於Name用於分組級別,其中object CollectionViewGroup.Name - Name的基本類型是分組的級別,因此級別1是InspectionType,級別2是Inspection

問題是,我使用的轉換器比我想要的要多,轉換此object Name並訪問我需要訪問和顯示的成員...但是,然後,我需要顯示每個分組中的項目,因此DataType應該是CollectionViewGroup ...對不對?

我怎樣才能做到這一點,而不訴諸於所有需要顯示的轉換器? 應該如何完成?我能找到的每一個TreeView/CollectionViewGroup教程都是一個簡單的實現。

回答

1

您已經遇到了XAML的標誌性問題:它幾乎是也是結構化的。

大多數慣用的解決方案是編寫一個自定義的WPF用戶控件。 (如何以及包含什麼是您的最佳選擇。)WPF用戶控件的目標是消除重複的XAML標記和邏輯。您可以將您的Converter包含在用戶控件中,並消除主控制器中的轉換器。

有很多關於在WPF中創建UserControl對象的教程,所以在此不再贅述。


至於Converter問題:這是幾乎最習慣的方法。每個轉換器都是可重用的,並且只關注一種源類型。除了考慮將支持相同源類型的轉換器合併在一起之外,您可以做的其他事情不多。 (轉換器有Type targetType參數和object parameter是有原因的。)