こんな感じのビヘイビアを定義しておきます。
using Microsoft.Xaml.Interactivity; using Windows.System; using Windows.UI.Core; using Windows.UI.Xaml; namespace App65 { public class KeyEventTriggerBehavior : DependencyObject, IBehavior { public DependencyObject AssociatedObject { get; private set; } public ActionCollection Actions { get { if (GetValue(ActionsProperty) == null) { this.Actions = new ActionCollection(); } return (ActionCollection)GetValue(ActionsProperty); } set { SetValue(ActionsProperty, value); } } public static readonly DependencyProperty ActionsProperty = DependencyProperty.Register( nameof(Actions), typeof(ActionCollection), typeof(KeyEventTriggerBehavior), new PropertyMetadata(null)); public bool ShiftKey { get { return (bool)GetValue(ShiftKeyProperty); } set { SetValue(ShiftKeyProperty, value); } } // Using a DependencyProperty as the backing store for ShiftKey. This enables animation, styling, binding, etc... public static readonly DependencyProperty ShiftKeyProperty = DependencyProperty.Register("ShiftKey", typeof(bool), typeof(KeyEventTriggerBehavior), new PropertyMetadata(false)); public bool CtrlKey { get { return (bool)GetValue(CtrlKeyProperty); } set { SetValue(CtrlKeyProperty, value); } } // Using a DependencyProperty as the backing store for CtrlKey. This enables animation, styling, binding, etc... public static readonly DependencyProperty CtrlKeyProperty = DependencyProperty.Register("CtrlKey", typeof(bool), typeof(KeyEventTriggerBehavior), new PropertyMetadata(false)); public VirtualKey Key { get { return (VirtualKey)GetValue(KeyProperty); } set { SetValue(KeyProperty, value); } } // Using a DependencyProperty as the backing store for Key. This enables animation, styling, binding, etc... public static readonly DependencyProperty KeyProperty = DependencyProperty.Register("Key", typeof(VirtualKey), typeof(KeyEventTriggerBehavior), new PropertyMetadata(VirtualKey.None)); public void Attach(DependencyObject associatedObject) { this.AssociatedObject = associatedObject; this.Register(); } public void Detach() { this.Unregister(); this.AssociatedObject = null; } private void Register() { var fe = this.AssociatedObject as FrameworkElement; if (fe == null) { return; } fe.Unloaded += this.Fe_Unloaded; Window.Current.CoreWindow.KeyDown += this.CoreWindow_KeyDown; } private void Unregister() { var fe = this.AssociatedObject as FrameworkElement; if (fe == null) { return; } fe.Unloaded -= this.Fe_Unloaded; Window.Current.CoreWindow.KeyDown -= this.CoreWindow_KeyDown; } private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args) { if (this.ShiftKey && (Window.Current.CoreWindow.GetKeyState(VirtualKey.Shift) & CoreVirtualKeyStates.Down) != CoreVirtualKeyStates.Down) { return; } if (this.CtrlKey && (Window.Current.CoreWindow.GetKeyState(VirtualKey.Control) & CoreVirtualKeyStates.Down) != CoreVirtualKeyStates.Down) { return; } if (this.Key == args.VirtualKey) { Interaction.ExecuteActions(this, this.Actions, args); args.Handled = true; } } private void Fe_Unloaded(object sender, RoutedEventArgs e) { this.Unregister(); } } }
こういう風に使います。
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App65" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" xmlns:Core="using:Microsoft.Xaml.Interactions.Core" x:Name="page" x:Class="App65.MainPage" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Interactivity:Interaction.Behaviors> <local:KeyEventTriggerBehavior Key="A" ShiftKey="True"> <local:KeyEventTriggerBehavior.Actions> <Core:CallMethodAction TargetObject="{Binding ElementName=page}" MethodName="Alert" /> </local:KeyEventTriggerBehavior.Actions> </local:KeyEventTriggerBehavior> <local:KeyEventTriggerBehavior Key="Enter" CtrlKey="True"> <local:KeyEventTriggerBehavior.Actions> <Core:CallMethodAction TargetObject="{Binding ElementName=page}" MethodName="Tweet" /> </local:KeyEventTriggerBehavior.Actions> </local:KeyEventTriggerBehavior> </Interactivity:Interaction.Behaviors> <Button Content="Click" /> </Grid> </Page>
課題としては、TextBoxみたいにキーイベントをかっさらってしまう奴にフォーカスがあるとショートカットが効かないという点でしょうか…Preview系イベントが恋しい。