代码之家  ›  专栏  ›  技术社区  ›  Duncan Edwards

我必须在WPF中显示按唱片集分组的曲目列表

  •  1
  • Duncan Edwards  · 技术社区  · 15 年前

    现在我知道我可能需要使用一个列表框,并且可以使用完全符合我需要的GroupStyle内容。唯一的事情是我被告知:

    每当在控件上设置“GroupStyle”时,布局项目的面板将从virtualizingstackpanel更改为stackpanel(这是MS代码中的一个黑客程序)。

    我需要使用此Mecahnism显示多达2000个曲目:

    1)此错误是否仍然存在?

    2)最多2000首曲目需要担心这一点吗?(更像是平均值50-100)

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

    2 回复  |  直到 15 年前
        1
  •  0
  •   Drew Noakes    15 年前

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

    2000个项目是否能充分执行将取决于应用于每个项目的模板的复杂性。我有一个 列表框 使用相对简单的模板(大约8 TextBlock S在水平方向 StackPanel )在应用分组的情况下,性能开始下降到大约1500项。它似乎还取决于将项目聚合到其中的组的数量,其中组的数量越多,性能就越差。由于某种原因滚动时,这一点尤其明显。

    列表框 使动态分组非常容易,但是如果您通常要按唱片集分组,那么最好设置 ItemsSource 你的 ItemsControl (也许是 列表框 )收集 Album 对象,每个对象都有一个 Tracks 属性本身是 Track 物体。假设这样,我看到两个选项:

    1. 使用嵌套 ItemsControls 专辑 DataTemplate
    2. 使用A HeaderedItemsControl TreeView 用一个 HierarchicalDataTemplate

    在选项1中,您必须手动管理选择。在最简单的实现中,您可以单独选择唱片集和曲目;可能会选择不属于所选唱片集的曲目。你可以不选择专辑,因为这不是我能想到的其他媒体播放器的曲目列表视图中的概念。

    解决方案一还涉及到从一张专辑的最后一首曲目到下一张专辑的第一首曲目的键盘导航。

    假设以下代码:

    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" }
            }
        }
    };
    

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

    <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>
    

    更换外部 列表框 项目控制 缓解选择问题,如所讨论的。你得让它看起来很漂亮,因为上面看起来很难看。

    选项二的定义如下:

    <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>
    

    ListView 通过xaml属性支持自3.5sp1起的可选用户界面虚拟化:

    VirtualizingStackPanel.IsVirtualizing="True"
    

    比亚斯托尔尼茨有 three great posts 但在这个话题上,正如她指出的那样,它们从SP1开始就过时了。

        2
  •  0
  •   Edward Bedwell    15 年前

    这不是臭虫……是设计出来的!