我必须在WPF中显示GROUPED BY Album的曲目列表

时间:2009-08-28 12:05:07

标签: wpf listbox group-by

现在我知道我可能需要使用ListBox并且可以使用完全100%满足我需求的GroupStyle内容。唯一的问题是我被告知:

“每当在控件上设置”GroupStyle“时,布局项目的面板从VirtualizingStackPanel变为StackPanel(这是MS代码中的黑客攻击)......”

我需要使用这种mecahnism显示多达2000首曲目:

1)这个bug是否仍然存在?

2)对于多达2000首曲目,这是否值得担心? (更像是平均50-100)

此外,用户不会更改group by。在整个控制期间,轨道将以相同的方式分组。

2 个答案:

答案 0 :(得分:0)

这不是一个错误...它是设计的!

答案 1 :(得分:0)

据我所知,ListBox在应用群组时仍会停止虚拟化项目。

2000项是否能够充分发挥将取决于应用于每个项目的模板的复杂性。我有一个ListBox,其中包含一个相对简单的模板(水平TextBlock中大约8 StackPanel s),并且在应用分组的情况下,大约1500个项目的性能开始下降。它似乎还取决于聚合项目的组的数量,其中更多的组导致性能降低。滚动时出于某种原因,这一点尤为明显。

ListBox使动态分组变得非常简单,但如果您通常会按照相册进行分组,那么最好设置ItemsSource的{​​{1}}(也许是{ {1}})是ItemsControl个对象的集合,每个对象都有一个ListBox属性,它本身就是Album个对象的集合。假设这一点,我看到两个选项:

  1. Tracks Track
  2. 中使用嵌套ItemsControls
  3. 使用Album,例如DataTemplateHeaderedItemsControl
  4. 在选项一中,您必须手动管理选择。在最简单的实现中,您可以单独选择专辑和曲目;可能选择了不属于所选专辑的曲目。您可以不选择专辑,因为这不是我能想到的其他媒体播放器的轨道列表视图中的概念。

    解决方案一也对从一张专辑的最后一首曲目到下一张专辑的第一首曲目的键盘导航产生影响。

    假设以下代码:

    TreeView

    以下是一些演示选项1的代码:

    HierarchicalDataTemplate

    将外部public class Album { public string Title { get; set; } public ObservableCollection<Track> Tracks { get; set; } } public class Track { public string Title { get; set; } } _tracks.ItemsSource = new[] { new Album { Title = "Album 1", Tracks = new ObservableCollection<Track> { new Track { Title = "Track 1" }, new Track { Title = "Track 2" } } }, new Album { Title = "Album 2", Tracks = new ObservableCollection<Track> { new Track { Title = "Track 1" }, new Track { Title = "Track 2" } } } }; 更改为<ListBox x:Name="_tracks"> <FrameworkElement.Resources> <DataTemplate DataType="{x:Type local:Track}"> <TextBlock Text="{Binding Path=Title}" /> </DataTemplate> <DataTemplate DataType="{x:Type local:Album}"> <StackPanel> <TextBlock Text="{Binding Path=Title}" /> <ListBox ItemsSource="{Binding Path=Tracks}" /> </StackPanel> </DataTemplate> </FrameworkElement.Resources> </ListBox> 以缓解选择问题,如上所述。你必须让它看起来很漂亮,因为上面看起来很丑陋。

    选项二可以这样定义:

    ListBox

    ItemsControl支持从3.5SP1开始通过XAML属性选择加入UI虚拟化:

    <TreeView x:Name="_tracks2">
        <FrameworkElement.Resources>
            <DataTemplate DataType="{x:Type local:Track}">
                <TextBlock Text="{Binding Path=Title}" />
            </DataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type local:Album}"
                                      ItemsSource="{Binding Path=Tracks}">
                <TextBlock Text="{Binding Path=Title}" />
            </HierarchicalDataTemplate>
        </FrameworkElement.Resources>
    </TreeView>
    

    Bea Stollnitz对此主题有three great posts,但她指出自SP1以来它们已经过时了。