首页 > 解决方案 > WPF KeyBinding 禁用并让键盘快捷键冒泡

问题描述

我正在开发一个使用 MVVM、KeyBinding 和 ICommand 的项目。

我在同一个窗口上有多个嵌套视图(用户控件),其中许多使用相同的 KeyBinding“Ctrl+S”来运行SaveCommand.

与 View 关联的 ViewModel 有一个IsSaveCommandAvailable属性,可以判断SaveCommand该 ViewModel 中是否可用。

在我的情况下,只有“根”视图必须能够SaveCommand通过按 Ctrl+S 来启动,嵌套的视图必须忽略按键并让它冒泡到根视图,这完成了所有的保存工作。

我搜索了一个解决方案,只发现我可以使用ICommand.CanExecute返回 false 并避免 KeyBinding 运行。

但是这个解决方案不符合我的需要,因为如果我在子视图上按 Ctrl+S,它的SaveCommandCanExecute 会返回 false,并且按键会丢失。

有没有办法在 KeyBinding 可以运行之前使按键冒泡?

标签: wpfxamlmvvmicommand

解决方案


我找到的解决方案是在 KeyBindingIValueConverterKey属性上使用 a,将布尔值转换为作为 CommandParameter 传递的键,如果值为false,则返回Key.None

public class BooleanToKeyConverter : IValueConverter
{

    /// <summary>
    /// Key to use when the value is false
    /// </summary>
    public Key FalseKey { get; set; } = Key.None;

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is bool flag && flag && parameter != null && parameter != DependencyProperty.UnsetValue)
        {
            if (parameter is Key key)
            {
                return key;
            }
            else if (Enum.TryParse<Key>(parameter.ToString(), out var parsedKey))
            {
                return parsedKey;
            }
        }
        return this.FalseKey;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

}

在资源文件(例如:App.xaml)中:

<conv:BooleanToKeyConverter x:Key="boolToKey"/>

其中“conv”是您的本地命名空间。

然后,在 KeyBindings 中:

<KeyBinding Command="{Binding Path=SaveCommand}" 
    Key="{Binding Path=IsSaveCommandAvailable, Converter={StaticResource boolToKey}, ConverterParameter=S}" 
    Modifiers="Ctrl"/>

推荐阅读