在特定键上使用EventTrigger

时间:2011-10-17 19:29:40

标签: wpf keydown interaction eventtrigger

我想在触摸特定键时使用EventTrigger调用命令(例如,空格键)

目前我有:

  <i:Interaction.Triggers>
       <i:EventTrigger EventName="KeyDown">
            <i:InvokeCommandAction Command="{Binding DoCommand}" CommandParameter="{BindingText}"/>
       </i:EventTrigger>
  </i:Interaction.Triggers>

现在我怎么能指定只有当空格键出现KeyDown时才会发生这种情况?

3 个答案:

答案 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的工作版本。 SpaceKeyDownEventMyControl自定义控件中定义,当未处理的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添加到另一个控件的模板中,从而允许后者将EventTriggerSpaceKeyDown路由事件一起使用:

<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>