【问题标题】:Why is my ComboBox taking so long to drop down when I run my program from within Visual Studio?当我在 Visual Studio 中运行我的程序时,为什么我的 ComboBox 需要很长时间才能下拉?
【发布时间】:2011-11-07 22:30:19
【问题描述】:

在我的视图模型中,我有两个相关的属性。他们的实现如下所示:

public string Code
{
   get { return _Code; }
   set
   {
      if (_Code != value)
      {
         _Code = value;
         OnPropertyChanged("Code");
         OnPropertyChanged("RelatedCodeList");
      }
}

public List<Code> RelatedCodeList
{
   get
   {
      return CodeLists[Code];
   }
}

CodeListsDictionary&lt;string, List&lt;Code&gt;&gt;

我有一个绑定到RelatedCodeListComboBox;它的实现如下所示:

<ComboBox SelectedItem="{Binding RelatedCode, Mode=TwoWay}"
          ItemsSource="{Binding RelatedCodeList}">

这看起来很简单,而且它有效,除了一件事。当我在 UI 中更改 Code 然后单击组合框时,需要两三秒才能下拉。即使列表中的项目少于 10 个。

是什么原因造成的?这不是集合更改事件:List 没有实现INotifyCollectionChanged,而且无论如何集合没有改变。它似乎没有发生在视图模型中;我在属性 getter 中设置了断点,一旦引发属性更改事件,getter 就会中断;当组合框下拉时,它们不会被调用。似乎不是项目渲染:没有为Code 类定义数据模板,在该类中实现ToString() 很简单。

我忽略了什么?

编辑

我跟进了 Will 的建议,发现除非我在调试器下运行,否则不会发生这种情况。如果我只是运行可执行文件(甚至是 Debug 版本),它的性能就很好。

因此,为了使这个问题真正有用,让我们改写一下:为什么会发生这种情况?而且,更重要的是,如果要怪调试器,我有什么办法可以告诉调试器正在把事情搞砸,这样我就不用花几个小时来寻找实际上并不存在的问题的原因?

【问题讨论】:

  • 输出窗口中有什么可疑的地方吗?我之前遇到过这样的事情,我认为这与 UI-Automation 无缘无故地抛出异常有关。如果您可以发布一些能够重现问题的独立代码,那将会很有帮助。
  • RelatedCode get 或 set 方法中是否有相关代码?您是否尝试过删除 SelectedItem 绑定?
  • 您的RelatedCodeList 收藏中有多少项?你的输出窗口中有BindingErrors吗?
  • 因为附加了调试器,而此时VS正在将一堆程序集加载到内存中?我最近经常遇到这种情况
  • 无绑定错误。 “输出”窗口中没有任何类型的例外。我已经对在这个过程中被调用的所有 setter 和 getter 进行了检测,而且没有一个需要多达 10 毫秒的时间。但是对于 Will 认为应该归咎于调试器的想法表示敬意:这不会发生在 VS 之外。

标签: c# wpf performance mvvm combobox


【解决方案1】:

这类问题真的很难回答,因为您没有真正提供足够的信息。您提供的任何内容都不会导致问题。

但是使用我惊人的推理能力,我建议您检查一下您没有发生任何循环 OnPropertyChanged 调用 - 我注意到这些可能会使调试器停止,但几乎不会被注意到。

否则,请检查您的 CodeLists 索引器。

【讨论】:

  • 我同意我提供的任何内容不应该导致问题。但我找不到其他任何东西。 CodeListsDictionary&lt;string, string&gt;,所以它的索引器(除非发生了 非常奇怪 的事情)很好。我为 PropertyChanged 事件连接了一个侦听器,那里也没有发生任何异常情况。
【解决方案2】:

我发现 WPF ComboBox 缺少虚拟堆栈面板,这使得 UI 渲染速度变慢。包括 Virtual Stack Panel 是一个完美的解决方案。

将关注添加到您的窗口/用户控制资源中

<ItemsPanelTemplate x:Key="VSP">
    <VirtualizingStackPanel/>
</ItemsPanelTemplate>

更新组合框 XAML -

<ComboBox ItemsSource="{Binding Path=MyDataSource}"  DisplayMemberPath="Name" SelectedValuePath="Id" ItemsPanel="{StaticResource VSP}"/>

【讨论】:

    猜你喜欢
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-08
    • 1970-01-01
    • 2022-11-05
    • 2020-02-28
    • 2021-03-12
    相关资源
    最近更新 更多