WPF KeyBinding отключает и позволяет всплывать сочетания клавиш - PullRequest
0 голосов
/ 14 марта 2019

Я работаю над проектом, который использует MVVM, KeyBinding и ICommand.

У меня в одном окне несколько вложенных видов (UserControls), и многие из них используют одну и ту же привязку клавиш "Ctrl + S" для запуска SaveCommand.

ViewModel, связанный с View, имеет свойство IsSaveCommandAvailable, которое может определить, доступна ли SaveCommand в этой ViewModel.

В моем случае, только «корневое» представление должно иметь возможность запустить SaveCommand, нажав Ctrl + S, вложенные должны игнорировать нажатие клавиши и позволить ему всплыть до корневого представления, что делает все вещи Сохранить.

Я гуглил, что нашел решение, и обнаружил, что могу использовать ICommand.CanExecute, чтобы вернуть false и избежать запуска KeyBinding.

Но это решение не соответствует моим потребностям, потому что если я нажму Ctrl + S на дочернем View, его SaveCommand CanExecute вернет false, а нажатие клавиши будет потеряно.

Есть ли способ вспомнить нажатие клавиши, пока связывание клавиш не будет запущено?

1 Ответ

1 голос
/ 14 марта 2019

Я нашел решение использовать IValueConverter для свойства Key KeyBinding, преобразовав логическое значение в ключ, переданный как 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" - это ваше локальное пространство имен.

Затем в привязках клавиш:

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