そういえば前から疑問なんだけど、フォームのイベント伝搬ってどう組むべきなんだ?

状況としてはよくある波形ビューワーで、表示先頭位置と倍率が変えられて、
カーソルが2つあって、フィットボタンを押すと画面にフィットするもの。
(カーソル0が画面の左端、カーソル1が画面の右端になるように、
自動的に表示先頭位置と倍率が調整され、再描画される)

(A) 表示先頭位置の変更→画面再描画
(B) 倍率の変更→画面再描画

とした場合、
フィットボタンを押す→
 表示先頭位置と倍率が自動的に変更される=普通は上記(A)または(B)に当たる
 →自動的に再描画される
となるのだが、ほとんどのケースで2回描画されてしまう。
そこで今は、倍率変更側はフォーカスを確認して

(B') 倍率の変更→(フォーカスがある時のみ)→画面再描画

として1回描画にしているが、
これだとフィットボタンを押したとき、結果的に倍率のみの変更の場合は再描画されない
(同じ値を上書きしてもChangedが発火しない)ので、フィットボタンのイベントの最後に
if (!changed_start_pos) redraw();
を付けている。
ただしこれはリファクタ時に久々に見たら「はて?」と思ってしまった。
この場合って、どう組むべきなんだ?

ちなみにJavaScriptの場合は、プログラムによる変更の場合はイベントが発火しないので、
全てのイベントの最後に redraw(); が必要になるが、全部書けば全く問題ない。
フォームの場合はプログラムによる変更でもイベントが発火するので、この問題が起きる。
ただ、特にレアケースでもないし、一般的なうまいやり方があるとは思うのだけど。
上手く繋げられれば記述が少なくて済むからこの仕様なんだろうし。