什么是具有CollectionViewGroup分组的惯用XAML TreeView?

Mat*_*don 6 c# wpf treeview xaml hierarchicaldatatemplate

我有一个TreeView看起来像这样:

<TreeView Grid.Row="1" x:Name="InspectionResultsTreeView"
          ItemsSource="{Binding Source={StaticResource InspectionTypeGroupViewSource}, Path=Groups}"
          ItemTemplate="{StaticResource InspectionTypeGroupsTemplate}">
</TreeView>
Run Code Online (Sandbox Code Playgroud)

ItemsSource是一个键入的资源,其名称为InspectionTypeGroupViewSource:

<CollectionViewSource x:Key="InspectionTypeGroupViewSource" Source="{Binding Results}">
    <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="Inspection.InspectionType" />
        <PropertyGroupDescription PropertyName="Inspection" />
    </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
Run Code Online (Sandbox Code Playgroud)

这个小东西的作用是采用ViewModel的Results属性:

private ObservableCollection<ICodeInspectionResult> _results;

public ObservableCollection<ICodeInspectionResult> Results
{
    get { return _results; } 
    set { _results = value; OnPropertyChanged(); }
}
Run Code Online (Sandbox Code Playgroud)

...和组它在两个层面上-首先InspectionType,然后Inspection-结果是与检查类型,检查,再检查用独立结果的3层次结构.在这一点上,截图可能有助于可视化我猜:

Rubberduck 2.0 Code Inspections工具窗口

因此,ItemTemplateInspectionResultsTreeView是另一个键的资源,由名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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

最后,ItemTemplate这个分组是一个InspectionResultTemplate,用于每个单独的检查结果:

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

ICodeInspectionResult接口有一个string Name是我在这里使用的财产; 这Name从不同Name的是在该分组级别,其中它是一个使用object CollectionViewGroup.Name-基础类型的即Name是,分组的,所以电平1是InspectionType,和水平2是Inspection.

问题是,我使用多个转换器比我相信我需要,转换这object Name并访问我需要访问和显示的成员......但后来,我需要在每个分组,以便显示的项目数量的DataType应该是CollectionViewGroup......吧?

如何在不使用转换器的情况下完成所有需要显示的内容?应该怎么做?我能找到的每个TreeView/ CollectionViewGroup教程都是一个简单的实现.

410*_*one 1

您遇到了 XAML 的标志性问题:它几乎过于结构化。

惯用的解决方案是编写自定义 WPF 用户控件。(如何以及在其中包含什么内容由您决定。)WPF 用户控件的目标是消除重复的 XAML 标记和逻辑。您可以将您的控制器包含Converter在用户控件中,并从主控件中删除转换器。

关于在 WPF 中创建对象的教程有很多UserControl,这里不再赘述。


就问题而言Converter:这几乎是最惯用的方式。每个转换器都是可重复使用的,并且仅专注于一种源类型。除了考虑将支持相同源类型的转换器合并在一起之外,您对此无能为力。Type targetType(转换器有一个参数和一个是有原因的object parameter。)