c# - 如何在运行时从用户分配键盘快捷键,WPF MVVM
问题描述
正如标题所说,我正在寻找一种在运行时使用 WPF MVVM 模式从用户分配键盘快捷键的方法。我知道我可以像这样在开始时定义键盘快捷键:
<Window.InputBindings>
<KeyBinding Command="{Binding MyCommand}" Key="A"/>
</Window.InputBindings>
我还看到有一种方法可以解析来自用户的输入绑定。然而,我正在努力将一个输入绑定从我的 ViewModel 绑定到 MainWindow 的 InputBinding。我不知道如何实现这一点。这是我的 MainWindow 中的代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel();
}
}
这是我的 ViewModel 中的一些示例代码:
public partial class MainWindowViewModel : Window, INotifyPropertyChanged
{
public MainWindowViewModel()
{
KeyBinding kb = new KeyBinding { Key = Key.T, Command = MyCommand };
this.InputBindings.Add(kb);
}
}
我知道这this.InputBindings.Add(kb);
部分可能应该换成别的东西;而是将键绑定添加到 MainWindow 的 InputBinding。但是,我不知道如何使用 MVVM 模式来做到这一点。因此:我将如何去做呢?
解决方案
您可能会在视图模型中定义输入绑定,但您仍然需要以某种方式将它们添加到视图中。
例如,您可以使用为您执行此操作的附加行为:
public class InputBindingsBehavior
{
public static readonly DependencyProperty InputBindingsProperty = DependencyProperty.RegisterAttached(
"InputBindings", typeof(IEnumerable<InputBinding>), typeof(InputBindingsBehavior), new PropertyMetadata(null, new PropertyChangedCallback(Callback)));
public static void SetInputBindings(UIElement element, IEnumerable<InputBinding> value)
{
element.SetValue(InputBindingsProperty, value);
}
public static IEnumerable<InputBinding> GetInputBindings(UIElement element)
{
return (IEnumerable<InputBinding>)element.GetValue(InputBindingsProperty);
}
private static void Callback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
UIElement uiElement = (UIElement)d;
uiElement.InputBindings.Clear();
IEnumerable<InputBinding> inputBindings = e.NewValue as IEnumerable<InputBinding>;
if (inputBindings != null)
{
foreach (InputBinding inputBinding in inputBindings)
uiElement.InputBindings.Add(inputBinding);
}
}
}
查看型号:
public partial class MainWindowViewModel
{
public MainWindowViewModel()
{
KeyBinding kb = new KeyBinding { Key = Key.T, Command = MyCommand };
InputBindings.Add(kb);
}
public List<InputBinding> InputBindings { get; } = new List<InputBinding>();
public ICommand MyCommand => ...
}
看法:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="Window18" Height="300" Width="300"
local:InputBindingsBehavior.InputBindings="{Binding InputBindings}">
<Grid>
</Grid>
</Window>
推荐阅读
- java - 无法为 @WebService 注释导入 javax.jws.webservice
- javascript - 将鼠标悬停在另一个图像上时更改图像位置
- ajax - 从托管在 S3 存储桶上的站点访问 AWS API 时出现 CORS 问题
- xaml - 如何使用 Shell 在 Xamarin Forms 4.8 版本的 Flyout 菜单和底部标签栏中定义不同的项目?
- javascript - JavaScript - 使用 toLocaleString() 将逗号添加到整数
- sql - 用于复杂过滤的 SQL 查询
- asp.net - 如何在 Xamarin 表单跨平台中将以下 Web Api 绑定或使用到 Picker?
- api - 如何从 Flutter 发出 MVC API 请求
- java - 如何在 groovy 的获取请求中传递您的用户名和密码?
- json - 如何在反应中使用 i18next json 进行映射