wpf UI 在打开包含大量项目的 Combobox 时冻结
wpf UI freezes when opening Combobox with a large number of items
我正在开发一个 WPF 应用程序,其中有一个组合框,其中 ItemsSource 绑定到来自数据库的 属性 5000 条记录。问题是,当我单击组合框的下拉箭头时,UI 没有响应或组合框响应时间过长。我搜索了它,但对我没有任何帮助。
代码如下:
<ComboBox IsEditable="True" ItemsSource="{Binding List,Mode=OneWay}" DisplayMemberPath="name" SelectedValue="{Binding SelectedItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
和属性
private ObservableCollection<Object> _List = new ObservableCollection<Object>();
public ObservableCollection<Object> List
{
get { return _List ; }
set { _List = value; OnPropertyChanged("List"); }
}
编辑:
这是在构造函数中加载数据的代码
public FormVM()
{
List = new ObservableCollection<Object>(db.cat.ToList());
}
您必须启用 UI 虚拟化。
目前 UI 您的 ComboBox
!
虚拟化被禁用
ListBox
或 ListView
等控件默认启用此功能。
ComboBox
等扩展 ItemsControl
的其他控件必须明确启用它。
启用UI虚拟化
ItemsControl
的 ItemsPresenter
(或 Panel.IsItemsHost
设置为 True
的任何 Panel
)必须是 ItemsControl
的子代ScrollViewer
.
ComboBox
.
已经是这种情况
必须将 ScrollViewer
配置为按项目(逻辑单位)而不是像素(物理单位)滚动,方法是将附加的 ScrollViewer.CanContentScroll
属性 设置为 True
.
ItemsControl
必须将其 ItemsPanel
设置为 VirtualizingStackPanel
.
必须通过将附加的属性 VirtualizingPanel.IsVirtualizing
设置为True
来启用VirtualizingPanel
的虚拟化模式。
例子
<ComboBox VirtualizingPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
可以通过启用延迟滚动来实现进一步的改进:
<ComboBox ScrollViewer.IsDeferredScrollingEnabled="True" />
满足以下条件之一将使UI无法虚拟化:
物品容器直接添加到ItemsControl
。例如,
如果应用程序明确地将 ListBoxItem
个对象添加到 ListBox
,
ListBox
不虚拟化 ListBoxItem
个对象。
ItemsControl
中的物品容器有不同的类型。为了
例如,使用 Separator
对象的菜单无法实现项目
回收,因为菜单包含 Separator
类型的对象和
MenuItem
.
将 CanContentScroll
设置为 false。
将 IsVirtualizing
设置为 false。
如果您遵循了所有约束,那么 UI 虚拟化就可以工作。然后,您遇到了与 UI 虚拟化无关的问题。如果您只使用 ComboBox
设置一个新的空项目,您应该不会遇到任何问题。
我正在开发一个 WPF 应用程序,其中有一个组合框,其中 ItemsSource 绑定到来自数据库的 属性 5000 条记录。问题是,当我单击组合框的下拉箭头时,UI 没有响应或组合框响应时间过长。我搜索了它,但对我没有任何帮助。
代码如下:
<ComboBox IsEditable="True" ItemsSource="{Binding List,Mode=OneWay}" DisplayMemberPath="name" SelectedValue="{Binding SelectedItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
和属性
private ObservableCollection<Object> _List = new ObservableCollection<Object>();
public ObservableCollection<Object> List
{
get { return _List ; }
set { _List = value; OnPropertyChanged("List"); }
}
编辑: 这是在构造函数中加载数据的代码
public FormVM()
{
List = new ObservableCollection<Object>(db.cat.ToList());
}
您必须启用 UI 虚拟化。
目前 UI 您的 ComboBox
!
ListBox
或 ListView
等控件默认启用此功能。
ComboBox
等扩展 ItemsControl
的其他控件必须明确启用它。
启用UI虚拟化
已经是这种情况ItemsControl
的ItemsPresenter
(或Panel.IsItemsHost
设置为True
的任何Panel
)必须是ItemsControl
的子代ScrollViewer
.
ComboBox
.必须将
ScrollViewer
配置为按项目(逻辑单位)而不是像素(物理单位)滚动,方法是将附加的ScrollViewer.CanContentScroll
属性 设置为True
.ItemsControl
必须将其ItemsPanel
设置为VirtualizingStackPanel
.必须通过将附加的属性
VirtualizingPanel.IsVirtualizing
设置为True
来启用VirtualizingPanel
的虚拟化模式。
例子
<ComboBox VirtualizingPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
可以通过启用延迟滚动来实现进一步的改进:
<ComboBox ScrollViewer.IsDeferredScrollingEnabled="True" />
满足以下条件之一将使UI无法虚拟化:
物品容器直接添加到
ItemsControl
。例如, 如果应用程序明确地将ListBoxItem
个对象添加到ListBox
,ListBox
不虚拟化ListBoxItem
个对象。ItemsControl
中的物品容器有不同的类型。为了 例如,使用Separator
对象的菜单无法实现项目 回收,因为菜单包含Separator
类型的对象和MenuItem
.将
CanContentScroll
设置为 false。将
IsVirtualizing
设置为 false。
如果您遵循了所有约束,那么 UI 虚拟化就可以工作。然后,您遇到了与 UI 虚拟化无关的问题。如果您只使用 ComboBox
设置一个新的空项目,您应该不会遇到任何问题。