我想在触摸特定键时使用EventTrigger调用命令(例如,空格键)
目前我有:
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyDown">
<i:InvokeCommandAction Command="{Binding DoCommand}" CommandParameter="{BindingText}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
现在我怎么能指定只有当空格键出现KeyDown时才会发生这种情况?
答案 0 :(得分:14)
您必须构建一个自定义触发器来处理:
public class SpaceKeyDownEventTrigger : EventTrigger {
public SpaceKeyDownEventTrigger() : base("KeyDown") {
}
protected override void OnEvent(EventArgs eventArgs) {
var e = eventArgs as KeyEventArgs;
if (e != null && e.Key == Key.Space)
this.InvokeActions(eventArgs);
}
}
答案 1 :(得分:11)
另一种方法是使用KeyBindings并将它们绑定到Window,UserControl,FrameworkElement等。这不会触发按钮,但是说你有一个从按钮调用的命令“MyCommand”,你可以调用它来自InputBindings的命令。
<UserControl.InputBindings>
<KeyBinding Command="{Binding Path=ApplyCommand}" Key="Enter"/>
<KeyBinding Command="{Binding Path=NextPage}" Modifiers="Ctrl" Key="Left"/>
</UserControl.InputBindings>
<StackPanel>
<Button IsDefault="True" Content="Apply">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Path=ApplyCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
您也可以将这些KeyBinding绑定到TextBox。
答案 2 :(得分:1)
我喜欢使用自定义触发器的想法,但是我没有设法使其实现(某些方法已更改或不建议使用,因此,SpaceKeyDownEventTrigger
的上述定义现在不编译)。因此,我在这里使用自定义RoutedEvent
的工作版本。 SpaceKeyDownEvent
在MyControl
自定义控件中定义,当未处理的OnKeyDown
附加事件到达KeyDown
并且按下的键是空格键时,会从MyControl
方法中引发
public class MyControl : ContentControl
{
// This constructor is provided automatically if you
// add a Custom Control (WPF) to your project
static MyControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(MyControl),
new FrameworkPropertyMetadata(typeof(MyControl)));
}
// Create a custom routed event by first registering a RoutedEventID
// This event uses the bubbling routing strategy
public static readonly RoutedEvent SpaceKeyDownEvent = EventManager.RegisterRoutedEvent(
"SpaceKeyDown",
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(MyControl));
// Provide CLR accessors for the event
public event RoutedEventHandler SpaceKeyDown
{
add { AddHandler(SpaceKeyDownEvent, value); }
remove { RemoveHandler(SpaceKeyDownEvent, value); }
}
// This method raises the SpaceKeyDown event
protected virtual void RaiseSpaceKeyDownEvent()
{
RoutedEventArgs args = new RoutedEventArgs(SpaceKeyDownEvent);
RaiseEvent(args);
}
// Here KeyDown attached event is customized for the desired key
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.Space)
RaiseSpaceKeyDownEvent();
}
}
可以将MyControl
添加到另一个控件的模板中,从而允许后者将EventTrigger
与SpaceKeyDown
路由事件一起使用:
<Style TargetType="{x:Type local:MyControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyControl}">
<Grid>
<ContentPresenter/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Adding MyControl to the TextBox template -->
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<local:MyControl>
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</local:MyControl>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="local:MyControl.SpaceKeyDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Foreground.Color"
From="White" To="Transparent" Duration="0:0:0.066" AutoReverse="True" RepeatBehavior="3x"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>