【问题标题】:WPF ListView grouping with expander via header template?WPF ListView 通过标题模板与扩展器分组?
【发布时间】:2018-01-26 06:27:43
【问题描述】:

我可以找到在 WPF 中将Expander 实现为ListView 的组的所有示例,方法是在GroupStyle.ContainerStyle 属性中为GroupItem 定义一个新的ControlTemplate

可以在here 找到一个这样的例子,它可以按预期工作。

但是它确实有一个缺陷,如果您添加额外的GroupDescriptions(用于多级分组),则第二级和后续级别没有缩进,就像仅覆盖标题模板而不是容器时那样风格。

我碰巧注意到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>

即。相同的核心Expander,但表示为HeaderTemplate,而不是ContainerStyle

几乎有效——在视觉上它看起来是正确的,甚至有多个级别的预期缩进。但是切换Expander实际上并没有显示或隐藏组中的项目,因此很明显视觉层次结构是错误的。

我有几个问题:

  1. 有没有办法让它像这样工作?
  2. 如果不是,GroupItemExpander 检测实际上做了什么,如果不是为了这个?
  3. 坚持原来的ContainerStyle,有没有办法保持自然压痕?

【问题讨论】:

    标签: c# .net wpf listview expander


    【解决方案1】:

    首先,如果你将Expander 放在标题模板中,GroupItem 将无法识别它(如果你检查source code(特别是this 辅助方法)你会明白为什么 - 它看起来对于后代Expander,但将TemplatedParent 设置为有问题的GroupItem,而如果Expander 是标题模板的一部分,则其TemplatedParent 将是ContentPresenter 1.

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

    最后,正确的做法是将Expander 放入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模板

    【讨论】:

    • 在多个层次结构级别使用相同样式时,如何确定要使用的正确边距? (另外,这不会缩进扩展头本身。)
    猜你喜欢
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 2014-01-02
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多