我正在开发一个使用MVVM,KeyBinding和ICommand的项目。
我在同一个窗口中有多个嵌套视图(UserControls),其中许多使用相同的KeyBinding“Ctrl + S”来运行SaveCommand
。
与View关联的ViewModel具有IsSaveCommandAvailable
属性,可以判断该ViewModel中是否有SaveCommand
。
在我的情况下,只有“root”视图必须能够通过按Ctrl + S来启动SaveCommand
,嵌套的必须忽略按键命中并让它冒泡到根视图,这将完成所有保存的东西。
我搜索了一个解决方案,但发现我可以使用ICommand.CanExecute
返回false并避免运行KeyBinding。
但是这个解决方案并不符合我的需要,因为如果我在子视图上按Ctrl + S,它的SaveCommand
CanExecute将返回false,并且键命中丢失。
有没有办法搞砸键击,直到可以运行KeyBinding?
我找到的解决方案是在KeyBinding的IValueConverter
属性上使用Key
,将布尔值转换为作为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"/>