设置带有图像内容的ToggleButton的快捷键

发布于 2024-09-06 12:26:58 字数 703 浏览 5 评论 0原文

我创建了一个 ToggleButton 来显示和隐藏一段 UI,并将其 Content 发送到一个图标。

我现在想向 ToggleButton 添加快捷键,但我不确定如何在不绑定命令的情况下进行操作。由于我所做的只是绑定到 IsChecked 状态,因此我不需要命令来执行任何其他功能,并且创建一个空命令似乎不正确。

这是我的 ToggleButton,因为它当前不起作用,并且当我按下指示的快捷键时没有响应。

<ToggleButton ToolTip="Command History"
              MinWidth="24"
              IsChecked="{Binding IsShowHistoryChecked}"
              Margin="7">
    <ToggleButton.InputBindings>
        <KeyBinding Gesture="Ctrl+H" />
    </ToggleButton.InputBindings>
    <Image Source="/Amuse;component/Images/ComHistory256.png"
           Width="24" />
</ToggleButton>

I've created a ToggleButton to show and hide a piece of UI and I've sent its Content to an icon.

I now want to add a shortcut key to the ToggleButton but I'm unsure how to do with without binding a command as well. Since all I am doing is binding to the IsChecked state, I don't need a command to do any other functionality and creating an empty one seems incorrect.

Here is my ToggleButton as it stands currently non-functional and not responding when I press the indicated shortcut key.

<ToggleButton ToolTip="Command History"
              MinWidth="24"
              IsChecked="{Binding IsShowHistoryChecked}"
              Margin="7">
    <ToggleButton.InputBindings>
        <KeyBinding Gesture="Ctrl+H" />
    </ToggleButton.InputBindings>
    <Image Source="/Amuse;component/Images/ComHistory256.png"
           Width="24" />
</ToggleButton>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

原谅过去的我 2024-09-13 12:26:59

ToggleButton 本身上的 InputBinding 并不能解决问题,但是有两个很好的 WPF 解决方案可以解决您的问题:

  1. 使用更新模型的 RoutedCommand。
  2. 注册访问密钥。

为什么您的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(如果文本框未处理,则按纯“h”),您的按钮将切换。

您也可以在 XAML 中执行此操作。如果您要在按钮中显示文本,只需在访问键字母之前使用下划线:

<Button Text="Show _History" ... />

如果您要显示的不仅仅是文本,请在按钮内容中包含一个隐藏的 AccessText 元素:

<Button ...>
  <Grid>
    <AccessText Text="_h" Visibility="Collapsed" />
    <Image ...>
  </Grid>
</Button>

如果您想知道,WPF 有没有内置机制来请求 AccessKey 注册响应 Ctrl 而不是 Alt,因此这将不允许您将 Ctrl-H 设置为访问键。

An InputBinding on the ToggleButton itself won't do the trick, but there are two good WPF solutions for your problem:

  1. Use a RoutedCommand that updates the model.
  2. Register an access key.

Why your InputBinding solution won't work

The InputBinding you have defined currently won't work because it doesn't list a command. It is easy to create a command that toggles a button, as follows:

public void Execute(object parameter)
{
  ((ToggleButton)parameter).IsChecked = !((ToggleButton)parameter).IsChecked;
}

However this will not achieve what you are looking for. You want Ctrl-H to toggle your button even when the button is not focused. An InputBinding will not accomplish this for you, since it only works when the button has focus. I will now discuss two solutions you can use.

Option 1: Use a RoutedCommand that updates the model

The whole point of WPF's architecture is that you never will need to "toggle a button" in the first place: Conceptually all keyboard and mouse actions in WPF should serve to toggle a bound property in your model or view model. The ToggleButton then just becomes the mechanism for accepting mouse clicks, but need not be the only one.

The name you chose for your "IsShowHistoryChecked" property indicates a fundamental problem in the way you're conceptualizing your view model. Your view model should not be designed around the view - rather, it should expose logical concepts such as a "ShowHistory" property. The view may bind this to a CheckBox or ToggleButton, or it may choose some other mechanism, or it may not expose it at all. The whole point of data binding and view models is that when you create the view model you don't care what the actual view will be like. In fact, during automated unit testing there will be no checkbox so "IsShowHistoryChecked" would clearly be a real misnomer.

So let's say you've properly separated your view from your view model and you have a "ShowHistory" property. First implement a "ToggleShowHistory" command in your view model that, when executed, toggles the ShowHistory property. Now all you have to do is assign this command an InputBinding of Ctrl-H at the view level and you're done. Even if the ToggleButton is removed from the view entirely the InputBinding will still take effect and Ctrl-H will still work. Nirvanna.

Option 2: Register an access key

Windows has a standard mechanism for associating keys with arbitrary buttons and labels, which is the "access key" concept. If you register an access key of "h" on the ToggleButton, pressing Alt-H will toggle the button, and so will just plain H if you don't have a TextBox or another control accept it first.

It is very simple to register the access key in code:

AccessKeyManager.Register("h", togleButton);

This registers "h" as the access text. Now if the user presses Alt-H anywhere in scope (or plain "h" if isn't handled by a TextBox), your button will toggle.

You can also do it in XAML. If you're showing text in your button, just use an underline before the access key letter:

<Button Text="Show _History" ... />

If you're showing something other than just text, include a hidden AccessText element in your button content:

<Button ...>
  <Grid>
    <AccessText Text="_h" Visibility="Collapsed" />
    <Image ...>
  </Grid>
</Button>

In case you're wondering, WPF has no built in mechanism to request that AccessKey registrations respond to Ctrl instead of Alt, so this will not allow you to set Ctrl-H as the access key.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文