私は最近、コードベースで非常に厄介な問題を回避するために修正しました。
基本的にコントロールを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
が作成したオブジェクトのハッシュ コードと一致しないのはなぜですか? また、ハンドラーが実行されるたびにハッシュ コードが変わるのはなぜですか?