gpt4 book ai didi

c# - 带有虚拟化的 ScrollIntoView 和 ListView

转载 作者:可可西里 更新时间:2023-11-01 08:30:01 27 4
gpt4 key购买 nike

我有 ListView(虚拟化默认开启),ItemsSource 绑定(bind)到 ObservableCollection<Item> 属性。

填充数据时(设置属性并发出通知)我在分析器中看到 2 个布局峰值,第二个发生在调用 listView.ScrollIntoView() 之后。

我的理解是:

  1. ListView 通过绑定(bind)加载数据并为屏幕上的项目创建 ListViewItem,从索引 0 开始。
  2. 然后我调用 listView.ScrollIntoView()
  3. 现在 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 的布局 channel 。我的目标是只拥有一个,但我不知道怎么做。

repro 的问题是模拟负载(在创建 ListViewItem is expensive 时),但我希望它现在能更清楚地说明问题。

最佳答案

Scroll 方法在 VirtualizingStackPanel 上通常不能很好地工作。为了解决这个问题,我使用了以下解决方案。

  1. 抛弃VirtualizingStackPanel。为面板模板使用普通的 StackPanel。
  2. 使您的 DataTemplate 的外层成为此处的 LazyControl:http://blog.angeloflogic.com/2014/08/lazycontrol-in-junglecontrols.html
  3. 确保在 LazyControl 上设置高度。

我通常会从这种方法中获得良好的性能。为了使其完全按照您的要求执行,您可能需要向 LazyControl 添加一些额外的逻辑以等待设置某些标志(在调用滚动方法之后)。

关于c# - 带有虚拟化的 ScrollIntoView 和 ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38303201/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com