Используйте EventTrigger на определенный ключ - PullRequest
12 голосов
/ 17 октября 2011

Я хотел бы вызвать команду, используя EventTrigger, когда прикоснулся к определенной клавише (например, клавиша пробела)

В настоящее время у меня есть:

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

Теперь, как я могу указатьчто это должно происходить только тогда, когда KeyDown происходит с пробелом?

Ответы [ 3 ]

14 голосов
/ 17 октября 2011

Вы должны создать собственный триггер для обработки:

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);
    }
}
11 голосов
/ 17 ноября 2015

Другим подходом может быть использование связывания клавиш и привязка их к вашему окну, 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>

Вы также можете привязать эти привязки клавиш к TextBox.

1 голос
/ 25 августа 2018

Мне нравится идея с пользовательским триггером, но мне не удалось заставить его работать (некоторые методы были изменены или устарели, поэтому приведенное выше определение 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...