【问题标题】:Exception while Refresh-ing Items of ListBox刷新 ListBox 项目时出现异常
【发布时间】:2013-07-10 16:56:56
【问题描述】:

我有一个带有 ListBoxButton 的 WFP 应用程序:

<Window x:Class="UITester.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
    Title="MainWindow" Height="350" Width="525">
        <ListBox Name="list"></ListBox>
        <Button Click="ButtonSelect_OnClick">Select Stuff</Button>
</Window>

在我后面的代码中:

public partial class MainWindow : Window
{
    private readonly Dictionary<int, int> _selected = new Dictionary<int, int>();

    public MainWindow()
    {
        InitializeComponent();

        list.ItemsSource = _selected.Values;
    }

    private void ButtonSelect_OnClick(object sender, RoutedEventArgs e)
    {
        _selected.Clear();
        for (int i = 0; i < 4; ++i)
        {
            _selected.Add(i, i);                
        }

        list.Items.Refresh();
    }
}

如果我在没有附加调试器的情况下运行应用程序,一切似乎都正常 - 我单击按钮,数字 0 到 3 出现在列表中。

但是,如果我在附加调试器的情况下运行它,我会看到在调用 list.Items.Refresh(); 行时会引发异常:

集合已修改;枚举操作可能无法执行。

据我所知,在枚举集合时尝试更改集合时会引发此异常。但我很确定情况并非如此。这里的一切都发生在 UI 线程中。首先,我将元素添加到字典中,只有在完成后,我才会刷新列表框中的项目。在我看来,什么都没有改变,事实上,什么都没有列举。 我想Refresh 方法枚举了字典的值,但它们已经更新并且在此枚举期间没有更改。

我知道这不是更新ListBox 的最佳方式,但它是更大更旧代码的一部分,我只是想了解这里出了什么问题。

更新

当我将_selected 更改为List&lt;int&gt; 并设置list.ItemsSource = _selected; 时,输出窗口中没有异常和警告。但是当我将 _selected 设置为 'HashSet` 时,问题又回来了。

【问题讨论】:

  • 您是否尝试将此代码移植到测试应用中,看看是否得到相同的结果?
  • @Dina,我在我的 VS2012 中检查了你的代码 sn-p。它工作正常,您提出的错误无法重现。您能否在测试应用程序中尝试此 sn-p 并查看问题仍然存在。如果是,请使用 c# 锁定技术使临界区线程安全。
  • 我无法重现错误...你能更好地解释一下你在做什么吗?
  • 看看这个:stackoverflow.com/questions/604831/… 虽然这看起来真的很奇怪。
  • @FabianBigler 但是,看不到 foreach。

标签: c# wpf exception listbox


【解决方案1】:

这不是一个完整的答案,因为我仍然不明白为什么会发生这种情况以及幕后发生了什么,但我已经说服自己我不应该担心这个。该异常发生在 WPF 框架的深处,并且可能在某处被捕获。通过查看输出窗口,我只能看到使用调试器运行时出现异常:

在 mscorlib.dll 中发生了“System.InvalidOperationException”类型的第一次机会异常

只有当我选择在抛出异常时中断,调试器才会真正中断。没有未处理的异常。

因此,虽然真正的原因仍然是个谜,但问题似乎不在我的代码中......

【讨论】:

    【解决方案2】:

    最好将您自己的列表与Dictionary 分开,并在Dictionary 更改时复制值。我建议使用ObservableCollection,这样您就不必进行刷新调用。

    我发誓我在某处仍有ObservableDictionary 的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-28
      • 2012-07-12
      相关资源
      最近更新 更多