私は最近、コードベースで非常に厄介な問題を回避するために修正しました。
基本的にコントロールをParentMenuItemBaseラップするクラスを派生さCommandBarPopupせ、子CommandBarButtonオブジェクトを作成し、それらのClickイベントを接続してICommand.
5 つの完全に無関係なコントロールの下に、RefactorRenameCommand最大 5 つの完全に独立したCommandBarButtonオブジェクトを接続したとします。CommandBarPopup
をクリックするCommandBarButtonと、child_Clickハンドラーは 5 回実行され、Ctrlパラメーターは 5 回の「クリック」すべてに対して同じハッシュ コードを持ちます。
次に、同じボタンをもう一度クリックすると、ハンドラーは再び 5 回実行され、Ctrlパラメーターは 5 回の「クリック」すべてに対して同じハッシュ コードを持ちますが、ハッシュ コードは最初のものとは異なります。もう一度クリックすると、そのパラメーターの新しいハッシュ コードが取得されます。
Ctrlそのパラメーターの最後のハッシュ コードをprivate staticフィールドに格納し、ハッシュ コードCtrlが異なる場合にのみハンドラーを実行することで、目的の動作を得ました。全然わからなくて汚くて言葉にならないくらい気持ち悪い。実際のコード内コメントを含む問題のハックは次のとおりです。
// note: HAAAAACK!!!
private static int _lastHashCode;
private void child_Click(CommandBarButton Ctrl, ref bool CancelDefault)
{
var item = _items.Select(kvp => kvp.Key).SingleOrDefault(menu => menu.Key == Ctrl.Tag) as ICommandMenuItem;
if (item == null || Ctrl.GetHashCode() == _lastHashCode)
{
return;
}
// without this hack, handler runs once for each menu item that's hooked up to the command.
// hash code is different on every frakkin' click. go figure. I've had it, this is the fix.
_lastHashCode = Ctrl.GetHashCode();
Debug.WriteLine("({0}) Executing click handler for menu item '{1}', hash code {2}", GetHashCode(), Ctrl.Caption, Ctrl.GetHashCode());
item.Command.Execute(null);
}
そのDebug.WriteLine呼び出しは次のようなものを出力します:
(46595510) Executing click handler for menu item '&Rename', hash code 16706408 (16139946) Executing click handler for menu item '&Rename', hash code 16706408 (11041789) Executing click handler for menu item '&Rename', hash code 16706408 (32267243) Executing click handler for menu item '&Rename', hash code 16706408 (21969731) Executing click handler for menu item '&Rename', hash code 16706408
次にクリックすると、パラメーターのハッシュ コードが異なることを除いて、同じ出力が生成されCtrlます。
では、このCtrlパラメータは正確には何ですか? CommandBarButtonクリックされたのが COM コントロールである場合、そのハッシュ コードCommandBarButtonが作成したオブジェクトのハッシュ コードと一致しないのはなぜですか? また、ハンドラーが実行されるたびにハッシュ コードが変わるのはなぜですか?