C# WPF ListView是否通过头模板使用扩展器分组?

C# WPF ListView是否通过头模板使用扩展器分组?,c#,.net,wpf,listview,expander,C#,.net,Wpf,Listview,Expander,我可以找到的所有示例都是通过为GroupStyle.ContainerStyle属性中的GroupItem定义一个新的ControlTemplate来将扩展器作为WPF中列表视图的一个组来实现的 我们可以找到一个这样的例子,它的工作原理与预期一致 但是,它确实存在一个缺陷,即如果添加额外的GroupDescriptions(用于多级分组),则第二级和后续级别不会出现缩进,就像只覆盖标题模板而不覆盖容器样式时一样 我无意中注意到,GroupItem代码似乎确实对在其模板中定位Expander控件提

我可以找到的所有示例都是通过为
GroupStyle.ContainerStyle
属性中的
GroupItem
定义一个新的
ControlTemplate
来将
扩展器作为WPF中
列表视图的一个组来实现的

我们可以找到一个这样的例子,它的工作原理与预期一致

但是,它确实存在一个缺陷,即如果添加额外的
GroupDescription
s(用于多级分组),则第二级和后续级别不会出现缩进,就像只覆盖标题模板而不覆盖容器样式时一样

我无意中注意到,
GroupItem
代码似乎确实对在其模板中定位
Expander
控件提供了特殊支持,这(如果是递归搜索)表明可以用更简单的样式替换上面的组样式,如下所示:

<GroupStyle>
    <GroupStyle.HeaderTemplate>
        <DataTemplate DataType="GroupItem">
            <Expander IsExpanded="True">
                <Expander.Header>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Name}"
                                   FontWeight="Bold" Foreground="Gray"
                                   FontSize="22" VerticalAlignment="Bottom" />
                        <TextBlock Text="{Binding ItemCount}" FontSize="22"
                                   Foreground="Green" FontWeight="Bold"
                                   FontStyle="Italic" Margin="10,0,0,0"
                                   VerticalAlignment="Bottom" />
                        <TextBlock Text=" item(s)" FontSize="22"
                                   Foreground="Silver" FontStyle="Italic"
                                   VerticalAlignment="Bottom" />
                    </StackPanel>
                </Expander.Header>
                <ItemsPresenter />
            </Expander>
        </DataTemplate>
    </GroupStyle.HeaderTemplate>
</GroupStyle>

即,相同的核心
扩展器
,但在
头模板
中表达,而不是在
容器样式
中表达

这几乎是可行的——从视觉上看,它看起来是正确的,甚至具有多个级别的预期缩进。但是,切换
扩展器
实际上不会显示或隐藏组中的项目,因此显然视觉层次结构是错误的

我有几个问题:

  • 有没有办法让它像这样工作
  • 如果不是,那么
    GroupItem
    Expander
    检测中实际做了什么
  • 坚持原来的
    容器样式
    ,有没有办法保持自然缩进

  • 首先,如果将
    Expander
    放在标题模板中,
    GroupItem
    将无法识别它(如果您检查(特别是helper方法)您将看到原因-它查找子体
    扩展器
    ,但将
    TemplatedParent
    设置为所讨论的
    组项
    ,而如果
    扩展器
    是标题模板的一部分,则其
    TemplatedParent
    将是
    内容呈现者
    1

    其次,即使它被识别,
    GroupItem
    也不能真正处理组项目的可见性-这是由
    Expander
    模板完成的(当它被展开时,它的
    内容
    可见,否则它就不可见).
    GroupItem
    仅在启用UI虚拟化并将其回收以表示另一个项目时处理一些边缘情况(基本上,它归结为使所有者
    ItemsControl
    上的度量无效)

    最后,正确的方法是将
    扩展器
    放入
    GroupItem
    模板(通过
    GroupStyle.ContainerStyle
    )中。如果盲目遵循引用的示例,则是的,不会有任何缩进。但是,您需要做的只是在
    ItemsPresenter
    上设置所需的边距,例如:

    <GroupStyle>
        <GroupStyle.ContainerStyle>
            <Style TargetType="{x:Type GroupItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type GroupItem}">
                            <Expander Header="{Binding Name}">
                                <ItemsPresenter Margin="20,0,0,0" />
                            </Expander>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </GroupStyle.ContainerStyle>
    </GroupStyle>
    
    
    
    瞧!-你有一个很好的(和“递归的”)缩进



    1假设您不覆盖默认的
    GroupItem
    模板。

    当在多个层次结构级别上使用相同样式时,如何确定要使用的正确边距?(另外,这不会缩进扩展标题本身。)