在XAML中使用键绑定捕获一系列字符

时间:2018-07-03 08:46:36

标签: c# wpf mvvm

我正在开发一种功能,用户可以按1槽9或“ a”至“ z”来执行列表中的命令。我为数字建立了支持,但是我真的不喜欢我的制作方法。

<Grid.InputBindings>
    <KeyBinding Command="{Binding ShortcutCharacterCommand}" Key="D0" CommandParameter="0" />
    <KeyBinding Command="{Binding ShortcutCharacterCommand}" Key="D1" CommandParameter="1" />
    <KeyBinding Command="{Binding ShortcutCharacterCommand}" Key="D2" CommandParameter="2" />
    <KeyBinding Command="{Binding ShortcutCharacterCommand}" Key="D3" CommandParameter="3" />
    <KeyBinding Command="{Binding ShortcutCharacterCommand}" Key="D4" CommandParameter="4" />
    <KeyBinding Command="{Binding ShortcutCharacterCommand}" Key="D5" CommandParameter="5" />
    <KeyBinding Command="{Binding ShortcutCharacterCommand}" Key="D6" CommandParameter="6" />
    <KeyBinding Command="{Binding ShortcutCharacterCommand}" Key="D7" CommandParameter="7" />
    <KeyBinding Command="{Binding ShortcutCharacterCommand}" Key="D8" CommandParameter="8" />
    <KeyBinding Command="{Binding ShortcutCharacterCommand}" Key="D9" CommandParameter="9" />
</Grid.InputBindings>

如果我以相同的方式实现其余字符,我将拥有大量的绑定列表。不仅支持字母,而且还支持数字键盘。我宁愿像在应用程序的另一部分中使用Winform控件一样使用以下代码来测试字符范围:

if (e.KeyValue >= '1' && e.KeyValue <= '9' ||
    e.KeyValue >= 'A' && e.KeyValue <= 'Z')
    {
        FavoriteShortcutKeyPressedCallBack.Raise(e.KeyValue);
    } 

我确实认为有可能,但我似乎无法制定出一种解决方案或在互联网上找到符合MVVM模式的解决方案。

所以基本上我的问题是,如何在WPF / MVVM中以更通用,更优雅的方式完成此任务?

我如何解决

我从mm8的答案中建议使用EventToCommandBinding。这导致XAML中出现以下代码:

<i:Interaction.Behaviors>
    <behaviors:EventToCommandBehavior Event="PreviewTextInput"
                                      Command="{Binding TextInputCommand}"
                                      PassArguments="True" />
</i:Interaction.Behaviors>

ViewModel有一个TextInputCommand,它从EventArgs中读取文本并选择相应的项目。

public RelayCommand<TextCompositionEventArgs> TextInputCommand { get; set; }

private void HandleTextInputCommand(TextCompositionEventArgs args)
{
   SelectItemBoundToShortcut(args.Text);
}

起初,我将KeyDown事件用作注释中建议的 user1672994 。但是发现我不得不考虑不同的键盘布局,并分别检查数字键盘字符。使用PreviewTextInput事件仅发送键入的文本,这正是我所需要的。

1 个答案:

答案 0 :(得分:2)

您可以处理PreviewKeyDown事件。在视图的代码中,您都可以在其中调用视图模型的命令:

private void Grid_PreviewKeyDown(object sender, KeyEventArgs e)
{
    var viewModel = DataContext as YourViewModel;
    if (viewModel != null)
    {
        switch (e.Key)
        {
            case Key.D0:
                viewModel.ShortcutCharacterCommand.Execute("0");
                break;
            case Key.D1:
                viewModel.ShortcutCharacterCommand.Execute("1");
                break;
                //...
        }
    }
}

或通过使用此处所述的交互触发器:

MVVM Passing EventArgs As Command Parameter

您还可以将事件处理程序中定义的功能包装在attached behaviour中。