Dir*_*mar 14 c# wpf events event-handling
在我的WPF应用程序中,我想将一个输入手势附加到命令,以便输入手势在主窗口中全局可用,无论哪个控件具有焦点.
在我的情况下,我想绑定Key.PageDown
到一个命令,但是,只要某些控件接收焦点(例如TextBox或TreeView控件),这些控件就会接收键事件并且不再触发命令.这些控件没有特定CommandBindings
或InputBindings
定义.
这是我定义输入手势的方式:
XAML:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" >
<StackPanel>
<TreeView>
<TreeViewItem Header="1">
<TreeViewItem Header="1.1"></TreeViewItem>
<TreeViewItem Header="1.2"></TreeViewItem>
</TreeViewItem>
<TreeViewItem Header="2" ></TreeViewItem>
</TreeView>
<TextBox />
<Label Name="label1" />
</StackPanel>
</Window>
Run Code Online (Sandbox Code Playgroud)
码:
using System;
using System.Windows;
using System.Windows.Input;
public static class Commands
{
private static RoutedUICommand _myCommand;
static Commands()
{
_myCommand = new RoutedUICommand("My Command",
"My Command",
typeof(Commands),
new InputGestureCollection()
{
new KeyGesture(Key.PageDown, ModifierKeys.None)
});
}
public static ICommand MyCommand
{
get { return _myCommand; }
}
}
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
CommandBinding cb = new CommandBinding();
cb.Command = Commands.MyCommand;
cb.Executed += new ExecutedRoutedEventHandler(cb_Executed);
cb.CanExecute += new CanExecuteRoutedEventHandler(cb_CanExecute);
this.CommandBindings.Add(cb);
}
void cb_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
void cb_Executed(object sender, ExecutedRoutedEventArgs e)
{
this.label1.Content = string.Format("My Command was executed {0}", DateTime.Now);
}
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试捕捉窗口的PreviewKeyDown
事件并将其标记为已处理这没有达到预期的效果.我也把Focusable
财产设置为false
.这有助于TextBox控件,但不适用于TreeView(并且具有不必要的效果,TextBox不再可以编辑,因此它不适合我).
所以我的问题是如何定义一个在主窗口无处不在的键盘快捷键?
Dir*_*mar 10
以下解决方法似乎具有将命令全局化到窗口所需的效果; 但是,我仍然想知道在WPF中是否有更简单的方法可以做到这一点:
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
foreach (InputBinding inputBinding in this.InputBindings)
{
KeyGesture keyGesture = inputBinding.Gesture as KeyGesture;
if (keyGesture != null && keyGesture.Key == e.Key && keyGesture.Modifiers == Keyboard.Modifiers)
{
if (inputBinding.Command != null)
{
inputBinding.Command.Execute(0);
e.Handled = true;
}
}
}
foreach (CommandBinding cb in this.CommandBindings)
{
RoutedCommand command = cb.Command as RoutedCommand;
if (command != null)
{
foreach (InputGesture inputGesture in command.InputGestures)
{
KeyGesture keyGesture = inputGesture as KeyGesture;
if (keyGesture != null && keyGesture.Key == e.Key && keyGesture.Modifiers == Keyboard.Modifiers)
{
command.Execute(0, this);
e.Handled = true;
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
使用PreviewKeyDown正是您应该做的...“PreviewXYZ”事件是从下往上触发的(因此窗口首先获取它,然后是控件)...这让您可以在“全局”上执行您想要执行的任何操作窗”级。
然后,您可以选择说“IsHandled = true”,这将阻止它进入下一个控件(就您而言),但您不必这样做。如果您希望事件冒泡,只需添加代码并将“IsHandled”保留为 false。
归档时间: |
|
查看次数: |
5550 次 |
最近记录: |