我最近修复了我的代码库中一个非常 烦人的问题。
我有一个ParentMenuItemBase
抽象类,从中派生出基本上包装CommandBarPopup
控件的类,并创建子CommandBarButton
对象并将它们的Click
事件连接起来以执行ICommand
.
假设我在 5 个完全不相关的控件下RefactorRenameCommand
连接了 5 个完全独立的CommandBarButton
对象。CommandBarPopup
当我单击 时CommandBarButton
,child_Click
处理程序将运行 5 次 -Ctrl
对于所有 5 次“单击”,该参数将具有相同的哈希码。
然后,如果我再次单击同一个按钮,处理程序将再次运行 5 次,并且Ctrl
对于所有 5 次“单击”,该参数将再次具有相同的哈希码,......但哈希码将与第一次不同时间 - 如果我再次单击,我将获得该参数的新哈希码。
我通过将该Ctrl
参数的最后一个哈希码存储在一个private static
字段中来获得所需的行为,并且仅在哈希码不同时才执行处理程序Ctrl
- 换句话说,我通过构建在我没有观察到的行为之上使其工作不完全理解,感觉很脏,让我无言以对。这是有问题的 hack,包括实际的代码内注释:
// 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
我创建的对象不匹配呢?为什么每次处理程序运行时它的哈希码都会改变?