使用WinForm ListView避免循环调用(和StackOverflowException)

时间:2012-03-26 14:55:43

标签: c# winforms sync stack-overflow

我的模型(表示为List)与ListView同步(没有使用数据绑定)时遇到问题。

  • ListView的每个项目对应于列表中的MyObject实例。
  • ListView还允许选中/取消选中与MyObject.IsVisible属性对应的项目。

当前解决方案: 每当MyObject列表发生更改时,我都会使用RefreshItems()方法擦除ListView的内容并重新生成其项目。 我还实现了ListView的ItemChecked事件。每当用户检查/取消选中一个项目时,我都会修改相应的MyObject.IsVisible属性。

问题是在后端更改MyObject.IsVisible时。 ListView中的相应复选框将不会更新。

失败的修复: 不知何故,我必须将MyObject.IsVisible的状态更改级联到ListView。例如,致电RefreshItems()。每当执行RefreshItems()时,都会自动调用ListView.ItemChanged事件。这会导致无限循环和stackoverflow异常。

  1. RefreshItems()=>根据模型更新ListView
  2. ListView已更改,因此ItemChecked被调用为我们拥有的项目的次数
  3. ItemChecked基于ListView
  4. 更新模型
  5. 模型更改导致cicle再次启动。 GOTO 1
  6. 在ItemChanged事件处理程序中,我无法检测是谁发起了更改(即通过单击用户或通过填充项目来刷新RefreshItems方法),因此我无法选择打开infinit循环。

    我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

在调用RefreshItems()之前,我将尝试分离ItemChanged的事件处理程序。
然后重新连接。

listView.ItemChanged -= new ItemChangedEventHandler(myItemChangedEvent);
RefreshItems();
listView.ItemChanged += new ItemChangedEventHandler(myItemChangedEvent);

答案 1 :(得分:0)

一些直接的想法:

1)如果RefreshItems()状态在模型中设置了不同的状态,则只调用itemChecked。通过模型设置器中的测试轻松完成。

2)在RefreshItems()中使用一些标记来记录您正在更新GUI的事实。如果设置了此标志,则不要在itemChecked处理程序中执行任何操作。然而,这对我来说感到讨厌和讨厌。