и проверка, совпадает ли новое значение со старым, здесь не применима (из-за колебаний расчета - я не устанавливаю то же значение в A и B, но преобразую).
Итак, вы говорите, что происходит нечто подобное:
A.Foo
устанавливается на x . A_FooChanged
устанавливает B.Bar
в f ( x ). B_BarChanged
устанавливает A.Foo
в g (f ( x )), что не x . A_FooChanged
устанавливает B.Bar
в f (g (f ( x ))).
и так далее.Это правильно?Потому что если g (f ( x )) равно x , то решение простое: B_BarChanged
следует установить только A.Foo
, если A.Foo
! =g (f ( x ).
Если предположить, что у этой рекурсии нет вычисляемого конечного состояния, то обработчикам событий требуется какой-то способ узнать контекст, в котором были сработаны обрабатываемые ими события).Вы не можете получить эту информацию из обычного протокола событий, потому что события предназначены для отделения операций, которые этот дизайн связывает.
Звучит так, как будто вам нужен внеполосный способ, чтобы эти элементы управления сигнализировалидруг другу. Это может быть так же просто, как использовать HashSet<EventHandler>
, это свойство Window
. Я хотел бы рассмотреть что-то вроде этого:
private void A_FooChanged(object sender, EventArgs e)
{
if (!SignalSet.Contains(B_BarChanged))
{
SignalSet.Add(A_FooChanged);
B.Bar = f(A.Foo);
SignalSet.Remove(A_FooChanged);
}
}
Это ломается, если A устанавливает B.Bar
, и B устанавливает C.Baz
, а C устанавливает A.Foo
, хотя я подозреваю, что сами требования нарушаются, если это происходит. В этом случае вам, вероятно, придется прибегнуть к просмотру трассировки стека. Это не красиво, но потомНичто в этой проблеме не очень красиво.