c# - 打开包含大量项目的组合框时 wpf UI 卡住

标签 c# wpf mvvm combobox

我正在开发一个 WPF 应用程序,其中我有一个组合框,其中 ItemsSource 绑定(bind)到来自数据库的 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>
和属性(property)
  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 虚拟化。
当前,您的 ComboBox 禁用了 UI 虚拟化。 !
ListBox 这样的控件或 ListView默认启用此功能。
其他扩展 ItemsControl 的控件喜欢 ComboBox必须明确启用它。
启用 UI 虚拟化

  • ItemsPresenter (或任何 PanelPanel.IsItemsHost 设置为 True )的 ItemsControl必须是 ScrollViewer 的 child .ComboBox 的情况已经如此。 .
  • ScrollViewer必须通过设置附加的 ScrollViewer.CanContentScroll 将其配置为按项目(逻辑单位)而不是像素(物理单位)滚动属性(property)给 True .
  • ItemsControl必须有它的ItemsPanel设置为 VirtualizingStackPanel .
  • VirtualizingPanel的虚拟化模式必须通过设置附加属性 VirtualizingPanel.IsVirtualizing 来启用至True .

  • 示例
    <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为假。
  • 设置IsVirtualizing为假。

  • 如果您遵循了所有约束,那么 UI 虚拟化确实有效。然后,您会遇到与 UI 虚拟化无关的问题。如果你要建立一个新的空项目,只有 ComboBox你应该不会遇到任何问题。

    关于c# - 打开包含大量项目的组合框时 wpf UI 卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62876109/

    相关文章:

    c# - 格式化 ASP.NET Gridview 货币值

    c# - 为什么我不能在 C# 中使用抽象静态方法?

    c# - 构建错误 MC1000 'Object reference doen' t 设置为实例

    c# - 在两个用户控件/ View 之间传递数据

    javascript - 无法从一个 View 模型更新另一个 View 模型的可观察值

    c# - 从应用程序内将包含 Mysql 数据的 HTML 电子邮件发送到表中

    c# - 在 C# 中实现通用数据结构时避免徘徊

    wpf - WPF 中切换按钮周围的轮廓

    .net - WinForm - WPF 集成;一片一片

    c# - 避免在 MVVM 模型中使用 ObservableCollection