WPF ListBox с ListBox - виртуализация UI и прокрутка

Мой прототип отображает "документы", которые содержат "страницы", которые представлены изображениями миниатюр. Каждый документ может иметь любое число страниц. Например, могло бы быть 1 000 документов с 5 страницами каждый или 5 документов с 1 000 страниц каждый или где-нибудь промежуток. Документы не содержат другие документы. В моей xaml разметке у меня есть a ListBox, чей ItemsTemplate ссылается на innerItemsTemplate, который также имеет a ListBox. Я хочу 2 уровня выбранных пунктов так, чтобы я мог выполнить различные операции на документах, или страницы (удалите, объединитесь, переместитесь в новое местоположение, и т.д.). innerItemsTemplate ListBox использование a WrapPanel как ItemsPanelTemplate.

Для сценария, где у меня есть большое количество документов с несколькими страницами каждый (говорят, 10 000 документов с 5 страницами каждый), прокрутка работает отлично благодаря Виртуализации UI VirtualizingStackPanel. Однако у меня есть проблемы, если у меня есть большое количество страниц. Документ с 1 000 страниц только отобразит приблизительно 50 за один раз (безотносительно соответствий на экране), и когда я прокручу вниз, внешнее ListBox перемещения к следующему документу, пропуская 950 страниц или так, чтобы не были видимы. Наряду с этим, существует нет VirtualzingWrapPanel таким образом, память приложения действительно увеличивается.

Я задаюсь вопросом, иду ли я об этом правильным путем, тем более, что это - вид трудных для объяснения! Я хотел бы смочь отобразить 10 000 документов с 1 000 страниц каждый (только показывающий любые соответствия на экране), с помощью Виртуализации UI и также гладкой прокрутки.

Как я могу удостовериться перемещения прокрутки через все страницы в документе, прежде чем он отобразит следующий документ, и все еще сохраните виртуализацию UI? Полоса прокрутки, кажется, только перемещается в следующий документ.

Кажется логичным представить "документы" и "страницы" - с моим существующим методом использования a ListBox в a ListBox?

Я был бы очень признателен за любые идеи, которые Вы имеете.Спасибо.

26
задан Adi Lester 24 July 2012 в 08:13
поделиться

2 ответа

Ответ здесь удивителен:

  • Если вы используете ItemsControl или ListBox, вы получите поведение, которое вы испытываете, когда элемент управления прокручивается "по пунктам", так что вы перепрыгиваете через весь документ сразу, НО
  • Если вы используете TreeView вместо этого, элемент управления будет прокручиваться плавно, так что вы сможете прокручивать документ и переходить к следующему, но он все равно будет способен виртуализироваться.

Я думаю, что причина, по которой команда WPF выбрала такое поведение, заключается в том, что TreeView обычно имеет элементы, которые больше видимой области, в то время как обычно ListBoxне имеет. В любом случае в WPF тривиально сделать так, чтобы TreeView выглядел и действовал как ListBox или ItemsControl, просто изменив ItemContainerStyle. Это очень просто. Вы можете свернуть свой собственный или просто скопировать соответствующий шаблон из файла системной темы.

Так что у вас будет нечто подобное:

<TreeView ItemsSource="{Binding documents}">
  <TreeView.ItemsPanel>
    <ItemsPanelTemplate>
      <VirtualizingStackPanel />
    </ItemsPanelTemplate>
  </TreeView.ItemsPanel>
  <TreeView.ItemContainerStyle>
    <Style TargetType="{x:Type TreeViewItem}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type TreeViewItem}">
            <ContentPresenter /> <!-- put your desired container style here  with a ContentPresenter inside -->
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </TreeView.ItemContainerStyle>
  <TreeView.ItemTemplate>
    <DataTemplate TargetType="{x:Type my:Document}">
      <Border BorderThickness="2"> <!-- your document frame will be more complicated than this -->
        <ItemsControl ItemsSource="{Binding pages}">
          ...
        </ItemsControl>
      </Border>
    </DataTemplate>
  </TreeView.ItemTemplate>
</TreeView>

Получение прокрутки на основе пикселей и мультивыбора в стиле ListBox для совместной работы

Если вы используете эту технику для получения прокрутки на основе пикселей, то ваш внешний ItemsControl, который показывает документы, не может быть ListBox (потому что ListBox не является подклассом TreeView или TreeViewItem). Таким образом, Вы теряете поддержку мультивыборов ListBox. Насколько я могу судить, нет способа использовать эти две возможности вместе, не включив часть своего кода для одной функции или другой.

Если вам нужны оба набора функциональности в одном управлении, у вас есть, по сути, несколько вариантов:

  1. Реализуйте мультивыбор самостоятельно в подклассе TreeViewItem. Используйте TreeViewItem вместо TreeView для внешнего элемента управления, так как он позволяет выбирать несколько дочерних элементов. В шаблоне внутри ItemsContainerStyle: Добавьте CheckBox вокруг ContentPresenter, шаблон привязывает CheckBox к IsSelected, и стиль CheckBox с шаблоном управления, чтобы получить тот вид, который вы хотите. Затем добавьте собственные обработчики событий мыши для обработки Ctrl-Click и Shift-Click для мультивыбора.

  2. Реализуйте виртуализацию с пиксельным прокруткой самостоятельно в подклассе VirtualizingPanel. Это относительно просто, так как большая часть сложности VirtualizingStackPanel связана с непиксельным скроллингом и переработкой контейнеров. Блог Дэна Кревьера имеет полезную информацию для понимания VirtualizingPanel.

25
ответ дан 28 November 2019 в 06:09
поделиться

Пожалуйста, позвольте мне предисловие к этому ответу с вопросом: Должен ли пользователь постоянно видеть каждую миниатюру внутри каждого элемента списка?

Если ответ на этот вопрос - "нет", тогда, возможно, можно было бы ограничить количество видимых страниц во внутреннем шаблоне элемента (учитывая, что Вы указали, что прокрутка хорошо работает, скажем, с 5 страницами) и использовать отдельный шаблон "выбранного элемента", который больше и отображает все страницы для этого документа? Билли Холлис объясняет, как "вытащить" выбранный элемент из списка на dnrtv эпизод 115

0
ответ дан 28 November 2019 в 06:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: