如果通过转换器以某种方式可能的话,我需要将 WPF UserControl 上的控件的可见性绑定到 Alt 键的状态。仅当按下 ALT 键时,该按钮才可见,该解决方案不应集成到代码隐藏文件中,因为我正在使用 PRISM/Unity 以严格的 MVVM 模式工作。
一个完美的解决方案将包括编写一个新的转换器,该转换器能够将键盘键的状态转换为用户控件的 Visiblity 属性,但我在转换器方面经验不足,无法自己提出解决方案.
如果通过转换器以某种方式可能的话,我需要将 WPF UserControl 上的控件的可见性绑定到 Alt 键的状态。仅当按下 ALT 键时,该按钮才可见,该解决方案不应集成到代码隐藏文件中,因为我正在使用 PRISM/Unity 以严格的 MVVM 模式工作。
一个完美的解决方案将包括编写一个新的转换器,该转换器能够将键盘键的状态转换为用户控件的 Visiblity 属性,但我在转换器方面经验不足,无法自己提出解决方案.
这是一个完整的例子
<Window x:Class="Playground.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Playground"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Title="MainWindow" Height="350" Width="525">
<Window.InputBindings>
<KeyBinding Modifiers="Alt" Key="LeftAlt" Command="{Binding AltPressedCommand}" />
</Window.InputBindings>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="boolToVisibilityConverter"/>
</Window.Resources>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewKeyUp">
<i:InvokeCommandAction Command="{Binding AltUnpressedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<Button Content="My Button" Visibility="{Binding IsAltPressed, Converter={StaticResource boolToVisibilityConverter}}"/>
</Grid>
</Window>
public class MainWindowViewModel : NotificationObject
{
public MainWindowViewModel()
{
AltPressedCommand = new DelegateCommand(() => IsAltPressed = true);
AltUnpressedCommand = new DelegateCommand(() => IsAltPressed = false);
}
public DelegateCommand AltPressedCommand { get; set; }
public DelegateCommand AltUnpressedCommand { get; set; }
private bool _IsAltPressed;
public bool IsAltPressed
{
get { return _IsAltPressed; }
set
{
if (value != _IsAltPressed)
{
_IsAltPressed = value;
RaisePropertyChanged("IsAltPressed");
}
}
}
}
控件的可见性通过 绑定到布尔属性BooleanToVisibilityConverter
。然后我使用两个命令。一个在使用 KeyBinding 按下 Alt 键时触发,第二个在键向上时触发。当您应该添加向上键时,我忽略了对Alt键的检查。如果您想纯粹使用 MVVM,这可能会变得很棘手,因为您需要向命令发送一个参数,说明正在按下的键。
我使用以下行为从PreviewKeyUp
事件传递关键参数
public class PreviewKeyUpBehavior : Behavior<UIElement>
{
#region Properties
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(PeviewKeyUpBehavior));
#endregion
#region Methods
protected override void OnAttached()
{
AssociatedObject.PreviewKeyUp += OnPreviewKeyUp;
base.OnAttached();
}
private void OnPreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
if (Command == null) return;
// Execute command and send the key as the command parameter
Command.Execute(e.Key == Key.System ? e.SystemKey : e.Key);
}
#endregion
}
这将在触发时引发绑定命令PreviewKeyUp
并将密钥作为命令参数发送。然后我将 View 和 ViewModel 中的代码更改如下:
<!-- Used behaviors instead of triggers -->
<i:Interaction.Behaviors>
<local:PreviewKeyUpBehavior Command="{Binding KeyUnpressedCommand}"/>
</i:Interaction.Behaviors>
将命令更改为采用可为空的键参数
public DelegateCommand<Key?> KeyUnpressedCommand { get; set; }
并实施
KeyUnpressedCommand = new DelegateCommand<Key?>(key =>
{
if (key == Key.LeftAlt)
IsAltPressed = false;
});
希望这可以帮助