Прокрутите список просмотра WPF до определенной строки. - PullRequest
22 голосов
/ 17 октября 2008

WPF, браузероподобное приложение.
Я получил одну страницу, содержащую ListView. После вызова функции PageFunction я добавляю строку в ListView и хочу прокрутить новую строку в представлении:

  ListViewItem item = ItemContainerGenerator.ContainerFromIndex(index) as ListViewItem;
  if (item != null)
    ScrollIntoView(item);

Это работает. Пока новая линия видна, она получает фокус, как и должна.

Проблема в том, что вещи не работают, когда строка не видна.
Если строка не видна, для сгенерированной строки нет ListViewItem, поэтому ItemContainerGenerator.ContainerFromIndex возвращает ноль.

Но без элемента, как прокрутить строку в поле зрения? Есть ли способ прокрутки до последней строки (или в любом месте) без необходимости ListViewItem?

Ответы [ 11 ]

0 голосов
/ 08 марта 2013

Чтобы преодолеть проблему виртуализации, но при этом использовать ScrollIntoView, а не взламывать кишки ListView, вы также можете использовать объекты ViewModel для определения того, что выбрано. Предполагая, что в вашем списке есть объекты ViewModel, которые имеют свойство IsSelected. Вы бы связали элементы с ListView в XAML следующим образом:

<ListView Name="PersonsListView" ItemsSource="{Binding PersonVMs}">
  <ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
      <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
    </Style>
  </ListView.ItemContainerStyle>
</ListView>

Затем метод code-behind может перейти к первому выбранному элементу следующим образом:

var firstSelected = PersonsListView.Items
    .OfType<TreeViewItemViewModel>().FirstOrDefault(x => x.IsSelected);
if (firstSelected != null)
    CoObjectsListView.ScrollIntoView(firstSelected);

Это также работает, если выбранный элемент находится вне поля зрения. В моем эксперименте свойство PersonsListView.SelectedItem было null, но, конечно, ваше свойство ViewModel IsSelected всегда там. Обязательно вызывайте этот метод после завершения всех привязок и загрузки (с правом DispatcherPriority).

Используя шаблон ViewCommand , ваш код ViewModel может выглядеть следующим образом:

PersonVMs.ForEach(vm => vm.IsSelected = false);
PersonVMs.Add(newPersonVM);
newPersonVM.IsSelected = true;
ViewCommandManager.InvokeLoaded("ScrollToSelectedPerson");
...