Чтобы преодолеть проблему виртуализации, но при этом использовать 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");