如何避免WPF中事件的递归触发?

gre*_*man 7 c# wpf recursion events

我有两个WPF(来自标准集)小部件A和B.当我改变A的某个属性时,它应该在B上设置,当它在B中改变时应该在A上设置.

现在我有这个丑陋的递归 - >我改变A,所以代码改变B,但是因为B改变了,它改变了A,所以它改变了B ......你有了图片.

如何避免这种递归最"标准"的方式?天真地删除和添加事件处理程序不起作用,并且检查新值是否与旧值相同在此处不适用(因为计算的波动 - 我没有将相同的值设置为A和B,但是已转换) .

背景

我总是尝试提供有关问题的最小信息以避免混淆.但是,这可能会有所帮助

  • 我没有写那些小部件,我只处理事件,就是这样
  • 尽管标题是"递归触发",处理程序会按顺序调用,因此您可以使用序列entry-exit-entry-exit-entry-exit,而不是entry-entry-entry-exit-exit-exit

    而最后一个,可能是最不重要的,但不过

  • 在这种特殊情况下,我有A和B的通用处理程序

A和B(在这种情况下)是滚动查看器,我尝试按比例保持两个相同的位置.该项目(由Karin Huber提供)在这里:http: //www.codeproject.com/KB/WPF/ScrollSynchronization.aspx

事件触发

阻止事件的想法非常受欢迎,我添加了触发事件的顺序,我们开始:

  • 我改变了A.
  • 调用一个处理程序
  • 我禁用了A的处理程序
  • 我改变了B(这是存储的,但没有触发)
  • 我启用了A的处理程序
  • 现在事件是从队列中获取的
  • 调用B处理程序
  • 我禁用B的处理程序
  • 我改变了A.
  • ...

如你所见,这是徒劳的.

Chr*_*isF 2

不要引发事件,而是重构代码,以便 A 和 B 的事件处理程序调用另一个方法来完成实际工作。

private void EventHandlerA(object sender, EventArgs e)
{
    ChangeA();
    ChangeB();
}

private void EventHandlerB(object sender, EventArgs e)
{
    ChangeB();
    ChangeA();
}
Run Code Online (Sandbox Code Playgroud)

如果直接或通过 B 更改 A 需要做一些细微不同的事情,那么您可以扩展/更改这些方法。

更新

鉴于您无法更改/无权访问代码,这不是解决方案。