ToggleButton 本身上的 InputBinding 无法解决问题,但是有两个很好的 WPF 解决方案可以解决您的问题:
- 使用更新模型的 RoutedCommand。
- 注册访问密钥。
为什么您的 InputBinding 解决方案不起作用
您当前定义的 InputBinding 将不起作用,因为它没有列出命令。创建一个切换按钮的命令很容易,如下所示:
public void Execute(object parameter)
{
((ToggleButton)parameter).IsChecked = !((ToggleButton)parameter).IsChecked;
}
但是,这不会达到您想要的效果。即使按钮未获得焦点,您也希望 Ctrl-H 切换按钮。InputBinding 不会为您完成此操作,因为它仅在按钮具有焦点时才有效。我现在将讨论您可以使用的两种解决方案。
选项 1:使用更新模型的 RoutedCommand
WPF 体系结构的全部要点是,您从一开始就不需要“切换按钮”:从概念上讲,WPF 中的所有键盘和鼠标操作都应该用于切换模型或视图模型中的绑定属性。ToggleButton 然后就变成了接受鼠标点击的机制,但不必是唯一的。
您为“IsShowHistoryChecked”属性选择的名称表明您在概念化视图模型的方式中存在一个基本问题。您的视图模型不应该围绕视图设计 - 相反,它应该公开诸如“ShowHistory”属性之类的逻辑概念。视图可能会将此绑定到 CheckBox 或 ToggleButton,或者它可能会选择一些其他机制,或者它可能根本不公开它。数据绑定和视图模型的全部意义在于,当您创建视图模型时,您并不关心实际视图会是什么样子。事实上,在自动化单元测试期间将没有复选框,因此“IsShowHistoryChecked”显然是一个真正的用词不当。
因此,假设您已经正确地将视图与视图模型分开,并且您有一个“ShowHistory”属性。首先在您的视图模型中实现“ToggleShowHistory”命令,该命令在执行时会切换 ShowHistory 属性。现在您所要做的就是在视图级别为这个命令分配一个 Ctrl-H 的 InputBinding,然后您就完成了。即使 ToggleButton 完全从视图中移除,InputBinding 仍将生效,并且 Ctrl-H 仍将起作用。涅槃。
选项 2:注册访问密钥
Windows 有一种将键与任意按钮和标签相关联的标准机制,即“访问键”概念。如果您在 ToggleButton 上注册了“h”访问键,则按 Alt-H 将切换按钮,如果您没有 TextBox 或其他控件首先接受它,则只需纯 H。
在代码中注册访问密钥非常简单:
AccessKeyManager.Register("h", togleButton);
这会将“h”注册为访问文本。现在,如果用户在范围内的任意位置按下 Alt-H(如果不是由 TextBox 处理,则按纯“h”),您的按钮将切换。
您也可以在 XAML 中执行此操作。如果您在按钮中显示文本,只需在访问键字母前使用下划线:
<Button Text="Show _History" ... />
如果您显示的不仅仅是文本,请在按钮内容中包含一个隐藏的 AccessText 元素:
<Button ...>
<Grid>
<AccessText Text="_h" Visibility="Collapsed" />
<Image ...>
</Grid>
</Button>
如果您想知道,WPF 没有内置机制来请求 AccessKey 注册响应 Ctrl 而不是 Alt,因此这将不允许您将 Ctrl-H 设置为访问键。