【问题标题】:How do I create collapsible group headers with child items in a ListBox?如何在 ListBox 中创建带有子项的可折叠组标题?
【发布时间】:2012-08-14 21:19:59
【问题描述】:

我有一个由分组数据填充的列表框,下面有一个标题和子项 - 我想自定义控件,使每个组标题都是一个扩展器(最初关闭),展开它会显示它下面的该组的项目

我还是 WPF 的新手,我该怎么做呢?我是否需要为 GroupStyle 的 HeaderTemplate(这里是否包含 ItemsPresenter?)和 ItemTemplate 实现数据模板,或者我是否需要在这两个数据模板之外创建一个全新的 ControlTemplate?

另外,对标题使用扩展器会禁用 ListBox 的项目虚拟化功能吗?如果是这样,我该怎么做才能确保不会发生这种情况?如果我将 VirtualizingStackPanel 放在 Expander 内容中,会减轻这种情况还是没有必要?

我的分组非常简单,只是一个字段上的平面集合:

ICollectionView collegeView = new ListCollectionView(playerDatabase);
collegeView.GroupDescriptions.Add(new PropertyGroupDescription("CollegeName"));
collegeView.SortDescriptions.Add(new SortDescription("CollegeName", ListSortDirection.Ascending));
collegeView.SortDescriptions.Add(new SortDescription("FirstName", ListSortDirection.Ascending));
lstCollege.ItemsSource = collegeView;

更新 这是我迄今为止尝试过的:

<ListBox x:Name="lstCollege" IsSynchronizedWithCurrentItem="True">
<ListBox.GroupStyle>
    <GroupStyle>
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                <Border Background="Blue" CornerRadius="5">
                     <Expander Header="{Binding Path=Name}" FontWeight="Bold" Foreground="White" Padding="3">
                         <ItemsPresenter />
                     </Expander>
                </Border>
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
    </GroupStyle>
</ListBox.GroupStyle>

<ListBox.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Vertical">
            <TextBlock>
                <TextBlock.Text>
                    <MultiBinding StringFormat="{}{0} {1}">
                        <Binding Path="FirstName" />
                        <Binding Path="LastName" />
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </StackPanel>
    </DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

不幸的是,这呈现的是每个组的扩展器,但是项目并未呈现在其中 - 它们呈现在组项目之外并且扩展器是空的

我认为发生这种情况的原因是因为 GroupItem 与 ListItem (或其他任何名称)分开呈现,因此 ListViewItem 不包含在每个 GroupItem 内......我认为 ListBox 呈现它的方式是 GroupItem, ListItem、ListItem、ListItem、GroupItem、ListItem 等

如何更改控件以使每个 GroupItem 也可以包含一组 ListItem?

【问题讨论】:

  • 发布一些代码会有所帮助 - 你到底是如何进行分组的?你的ItemsSource 是平的吗?标题和项目都在同一个列表中吗?还是标题复杂类型具有定义子级的属性?我不相信在 DataTemplate 中使用 Expander 会自动阻止虚拟化。
  • 发布了示例代码。我的问题的重点更多是为了获得我所描述的行为,我需要实现的最低限度是什么——我可以只定义 DataTemplates 还是需要定义整个 ControlTemplate?如果我需要创建一个 ControlTemplate,我需要做的最低限度是什么才能保留 ListBox 功能?
  • 好的,您使用 ICollectionView 的事实说明了您是如何进行分组的。请参阅下面的答案。

标签: c# .net wpf


【解决方案1】:

您应该能够创建GroupStyle 并专门使用ContainerStyle 来定义可使用扩展器折叠的组。这不需要DataTemplateControlTemplate,因为它特定于分组功能。看看 MSDN 上的 'GroupStyle.ContainerStyle' 属性,this other answer 也提供了一个例子。

【讨论】:

  • 恐怕我不确定您的意思 - ContainerStyle 如何“定义可使用 Expander 折叠的组”?在您链接的示例中,我已经通过 IValueConverter 对自定义分组进行了类似的操作...... ContainerStyle 如何帮助这个示例,为每个 GroupItem 创建 Expander 控件,因为它所做的只是设置属性 - 我没有看看我如何不需要定义 DataTemplate 或 ControlTemplate,因为我正在更改 ListBox 控件的默认外观和行为?
  • 在上面的代码中,您正在为标题创建Expander,而不是为其中包含项目的容器。尝试更改代码以使用GroupStyle.ContainerStyle 而不是GroupStyle.HeadterTemplate。然后再看看上面的 ContainerStyle 链接,看看他们是如何添加一个扩展器以在容器中使用(而不是标题)。
  • 非常感谢 - 我是个白痴,我只阅读了该 MSDN 页面上的描述,而没有费心看下面的示例..愚蠢的我!非常好 - 也很棘手......涉及使用 ContainerStyle 替换每个 GroupItem 的 ControlTemplate
  • @blue18hutthutt 你的最终解决方案是什么样的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-18
  • 1970-01-01
  • 2015-04-19
  • 2017-04-27
  • 1970-01-01
相关资源
最近更新 更多