ListBox, VirtualizingStackPanel и плавная прокрутка в WPF

У меня есть ListBox которые могут иметь много строк шаблонных записей БД, в том числе Imageпривязанный к ObservableCollection<MyItem>, Иногда коллекция может содержать тысячи предметов.

Производительность отличная, но прокрутка - это поведение по умолчанию. Я бы хотел, чтобы у него была плавная прокрутка, поэтому я снял флажок ScrollViewer.CanContentScroll,

Теперь у меня плавная прокрутка, но производительность ужасна: данные извлекаются в отдельном потоке, и поток быстро завершается, но для отображения результатов в течение 10-20 секунд ListBox, Я предполагаю, что это потому, что снятие отметки ScrollViewer.CanContentScroll изменяет базовый VirtualizingStackPanel к регулярному StackPanel и поэтому он загружает всю коллекцию перед отображением результатов.

Итак, мой вопрос заключается в следующем: как сохранить плавную прокрутку, не жертвуя VirtualizingStackPanel поведение и производительность?

3 ответа

Решение

Когда вы снимаете галочку с CanContentScroll, вы теряете виртуализацию. И ответ действительно расстраивает: пока нет готового решения:(.

PS: Это не первый пост здесь, задающий этот самый вопрос.

Если вы используете.NET 4.5 (или 4.0, если хотите немного взломать), здесь есть ответ.

[Обратите внимание, что комментарий @Guilluame был здесь задолго до этого ответа, но он не был особенно заметен при поиске ответов.]

Для тех, кто ищет в 2021 году, вы можете использовать такое решение:

Вы будете продолжать прокручивать и виртуализировать одновременно

                  <ItemsControl x:Name="TestIC" Grid.Row="1"
                ScrollViewer.CanContentScroll="True"
                VirtualizingPanel.IsVirtualizing="True"
                VirtualizingPanel.VirtualizationMode="Recycling" >
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.Template>
                    <ControlTemplate>
                        <Border
                            Padding="{TemplateBinding Control.Padding}"
                            Background="{TemplateBinding Panel.Background}"
                            BorderBrush="{TemplateBinding Border.BorderBrush}"
                            BorderThickness="{TemplateBinding Border.BorderThickness}"
                            SnapsToDevicePixels="True">
                            <ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
                                <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                            </ScrollViewer>
                        </Border>
                    </ControlTemplate>
                </ItemsControl.Template>
            </ItemsControl>
Другие вопросы по тегам