У меня есть ListView
(по умолчанию включена виртуализация), которая ItemsSource
привязана к свойству ObservableCollection<Item>
.
Когда данные заполняются (свойство установлено, и уведомление увеличивается) Я вижу 2 макета раскладки в профилировщике, второй - после вызова listView.ScrollIntoView()
.
Мое понимание:
-
ListView
загружает данные через привязку и создаетListViewItem
для элементов на экране, начиная с индекса 0. - Затем я вызываю
listView.ScrollIntoView()
. - И теперь
ListView
делает это второй раз (созданиеListViewItem
s).
Как предотвратить эту деин виртуализацию в два раза (я не хочу, чтобы это произошло до ScrollIntoView
)?
Я попытался сделать репрограммирование с помощью ListBox
.
XAML:
<Grid>
<ListBox x:Name="listBox" ItemsSource="{Binding Items}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button Content="Fill" VerticalAlignment="Top" HorizontalAlignment="Center" Click="Button_Click" />
</Grid>
CS:
public class NotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string property = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
public class ViewModel : NotifyPropertyChanged
{
public class Item : NotifyPropertyChanged
{
bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
OnPropertyChanged();
}
}
}
ObservableCollection<Item> _items = new ObservableCollection<Item>();
public ObservableCollection<Item> Items
{
get { return _items; }
set
{
_items = value;
OnPropertyChanged();
}
}
}
public partial class MainWindow : Window
{
ViewModel _vm = new ViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = _vm;
}
void Button_Click(object sender, RoutedEventArgs e)
{
var list = new List<ViewModel.Item>(1234567);
for (int i = 0; i < 1234567; i++)
list.Add(new ViewModel.Item());
list.Last().IsSelected = true;
_vm.Items = new ObservableCollection<ViewModel.Item>(list);
listBox.ScrollIntoView(list.Last());
}
}
Debug - Performance Profiler - Application Timeline... подождите немного, нажмите кнопку, подождите немного, закройте окно. Вы увидите 2 макета с VirtualizingStackPanel
. Моя цель - иметь только один, и я не знаю, как это сделать.
Проблема с воспроизведением заключается в том, чтобы имитировать нагрузку (при создании ListViewItem
стоит дорого), но я надеюсь, что это более четко продемонстрирует проблему сейчас.