如何移除通过CommandManager.RegisterClassInputBinding添加的输入绑定?

7
我使用CommandManager.RegisterClassInputBinding向整个类添加绑定。现在我想要删除它。
这是我测试过的内容。
private void CommandBinding_Executed_1(object sender, ExecutedRoutedEventArgs e)
{
    CommandManager.RegisterClassInputBinding(
        typeof(TextBox),
        new InputBinding(TestCommand, new KeyGesture(Key.S, ModifierKeys.Control)));


    MessageBox.Show("CommandBinding_Executed_1");
}

该方法在按下Ctrl+H时调用,并为Ctrl+S注册新的输入绑定。如果我先按下Ctrl+S,再按下Ctrl+H,它将不起作用,但是如果我先按下Ctrl+H,再按下Ctrl+S,它就可以工作了。
我检查了sender.InputBindings,只有一个绑定(Ctrl+S),因此我得出结论:RegisterClassInputBinding()不会将绑定添加到每个现有实例中,而是将绑定存储到与类关联的位置,然后将其与已处理的手势进行比较。
但是为什么没有RemoveClassInputBinding()方法呢?:( 编辑
我甚至通过反射成功实现了我的目标,但仍然找不到本地方法,虽然实现这个方法很简单。
var fieldInfo = typeof(CommandManager).GetField(
    "_classInputBindings", BindingFlags.Static | BindingFlags.NonPublic);
var fieldData = (HybridDictionary)fieldInfo.GetValue(null);
var inputBindingCollection = (InputBindingCollection)fieldData[typeof(TextBox)];
foreach (var o in inputBindingCollection)
{
    if (o == inputBinding)
    {
        MessageBox.Show("half way there");
    }
}
inputBindingCollection.Remove(inputBinding);

你是否想要像Visual Studio一样实现关键按键组合?如果是的话,这篇文章可能会对你有所帮助:http://kent-boogaart.com/blog/multikeygesture - CodeNaked
1个回答

8

ApplicationCommands.NotACommand 就是为这个目的而设计的:

“该命令始终被忽略,不处理引起它的输入事件。这提供了一种关闭现有控件中内置的输入绑定的方法。”

以你的例子为例:

CommandManager.RegisterClassInputBinding(
    typeof(TextBox),
    new InputBinding(
        ApplicationCommands.NotACommand,
        new KeyGesture(Key.S, ModifierKeys.Control)));

在我看来,这个代码看起来非常有缺陷。我正在编写一个快捷键管理器,允许用户添加/删除输入绑定。据我所知,如果用户按照您建议的方式删除绑定,绑定仍将存在,并且每次用户这样做时都会累积。这是正确的吗? - Sergej Andrejev
我不确定,我只是转达了微软的建议。但我可以告诉你,使用反射肯定存在缺陷。我会通过Reflector来查看是否有MS特殊情况下的NotACommand。 - user7116
CommandManager.TranslateInput(内部方法)有特殊情况需要处理,以确保不会执行NotACommand命令:“if ((command!= null) && (command!= ApplicationCommands.NotACommand))”。 - user7116
啊哈,但仍然有点奇怪他们没有允许删除,使用NotACommand确实会留下一些垃圾。 - Sergej Andrejev
我同意,虽然我相信我们可能忽略了其他设计方面的考虑。 - user7116
我认为不提供Unregister...()方法背后的动机是这样的,即这种类级别的绑定旨在是永久性的。如果您的绑定需要出现和消失,那么它应该在其他地方进行管理。或者,如果它通常需要存在,但在某些特定情况下您想要禁用它,那么与其执行上述操作(全局禁用),您应该在该上下文中创建一个NotACommand命令绑定(例如,在窗口的InputBindings集合中)。 - Peter Duniho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接