Я должен отобразить список треков GROUPED BY Album в WPF - PullRequest
1 голос
/ 28 августа 2009

Теперь я знаю, что мне, вероятно, нужно использовать ListBox и я могу использовать материал GroupStyle, который полностью на 100% соответствует моим потребностям. Единственное, что мне сказали, что:

"Всякий раз, когда" GroupStyle "установлен на элементе управления, панель, которая размещает элементы, изменяется с VirtualizingStackPanel на StackPanel (это взлом в коде MS) ..."

Мне нужно будет отобразить до 2000 треков, используя этот механизм:

1) Эта ошибка все еще существует?

2) О чем беспокоиться, если до 2000 треков? (Больше похоже на в среднем 50-100)

Также, группа не будет изменена пользователем. Треки будут сгруппированы одинаково на протяжении всего контроля.

Ответы [ 2 ]

0 голосов
/ 29 августа 2009

Насколько я знаю, ListBox по-прежнему останавливает виртуализацию элементов при применении групп.

Будет ли 2000 элементов работать должным образом, зависит от сложности шаблона, примененного к каждому элементу. У меня есть ListBox с относительно простым шаблоном (около 8 TextBlock с по горизонтали StackPanel), и производительность начинает снижаться примерно до 1500 элементов с применением группировки. По-видимому, это также зависит от количества групп, в которые агрегируются элементы, где большее количество групп приводит к снижению производительности. Это особенно заметно при прокрутке по какой-то причине.

ListBox делает динамическую группировку очень простой, но если вы обычно собираетесь группировать по альбомам, то, возможно, было бы лучше установить ItemsSource вашего ItemsControl (возможно, ListBox) как коллекция Album объектов, каждый из которых имеет свойство Tracks, которое само является коллекцией Track объектов. Предполагая это, я вижу два варианта:

  1. Использовать вложенные ItemsControls в Album DataTemplate
  2. Используйте 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" }
        }
    }
};

Вот код, демонстрирующий первый вариант:

<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, чтобы облегчить проблему выбора, как обсуждалось. Вы должны будете заставить это выглядеть симпатичным все же, поскольку вышеупомянутый выглядит довольно уродливым.

Второй вариант можно определить так:

<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 поддерживает opt-in виртуализацию пользовательского интерфейса начиная с 3.5SP1 через атрибут XAML:

VirtualizingStackPanel.IsVirtualizing="True"

У Bea Stollnitz есть три замечательных сообщений на эту тему, хотя она указывает, что они устарели с SP1.

0 голосов
/ 28 августа 2009

Это не ошибка ... это специально!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...