我正在开发MVVM应用程序,我想为我的应用程序创建全局快捷方式。有必要在模块之间导航应用程序。我有主窗口代码:
<UserControl.InputBindings>
<KeyBinding Command="{Binding ChangeModuleComand}"
Key="M"
Modifiers="Control"/>
</UserControl.InputBindings>
当我专注于我的窗口时,它会起作用,
但是当我在UserControl中关注TextBox时会出现问题(命令未被触发)。
是否有可能在整个应用程序中没有大量修改的情况下捕获关键压力?
一个。
答案 0 :(得分:2)
听起来你的事件在它起泡之前就被处理了。接下来我想知道你是否可以将输入绑定移动到窗口而不是用户控件。我的最后一个选择是删除输入绑定并创建全局检入代码。
由于您已经在使用输入绑定,我在下面添加了代码选项:
//In App.xaml.cs
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
EventManager.RegisterClassHandler(typeof(UIElement), UIElement.KeyDownEvent, new RoutedEventHandler(GlobalClick));
}
private void GlobalClick(object sender, RoutedEventArgs e)
{
var args = (KeyEventArgs) e;
if (args.KeyboardDevice.IsKeyDown(Key.M) &&
args.KeyboardDevice.IsKeyDown(Key.LeftCtrl) || args.KeyboardDevice.IsKeyDown(Key.RightCtrl))
MessageBox.Show("Works");
}
答案 1 :(得分:0)
为其他人记录这个答案,因为有一种更简单的方法可以做到这一点很少被引用,并且根本不需要触及XAML。
要在Window级别链接键盘快捷键,只需在Window构造函数中添加一个新的KeyBinding到InputBindings集合。作为命令,传入实现ICommand的任意命令类。对于execute方法,只需实现您需要的任何逻辑。在下面的示例中,我的WindowCommand类接受一个委托,它将在每次调用时执行。当我构造新的WindowCommand以传入我的绑定时,我只是在我的初始化器中指出我希望WindowCommand执行的方法。
您可以使用此模式提供自己的快捷键盘快捷键。
public YourWindow() //inside any WPF Window constructor
{
...
//add this one statement to bind a new keyboard command shortcut
InputBindings.Add(new KeyBinding( //add a new key-binding, and pass in your command object instance which contains the Execute method which WPF will execute
new WindowCommand(this)
{
ExecuteDelegate = TogglePause //REPLACE TogglePause with your method delegate
}, new KeyGesture(Key.P, ModifierKeys.Control)));
...
}
创建一个简单的WindowCommand类,它接受一个执行委托来触发任何设置的方法。
public class WindowCommand : ICommand
{
private MainWindow _window;
//Set this delegate when you initialize a new object. This is the method the command will execute. You can also change this delegate type if you need to.
public Action ExecuteDelegate { get; set; }
//You don't have to add a parameter that takes a constructor. I've just added one in case I need access to the window directly.
public WindowCommand(MainWindow window)
{
_window = window;
}
//always called before executing the command, mine just always returns true
public bool CanExecute(object parameter)
{
return true; //mine always returns true, yours can use a new CanExecute delegate, or add custom logic to this method instead.
}
public event EventHandler CanExecuteChanged; //i'm not using this, but it's required by the interface
//the important method that executes the actual command logic
public void Execute(object parameter)
{
if (ExecuteDelegate != null) //let's make sure the delegate was set
{
ExecuteDelegate();
}
else
{
throw new InvalidOperationException("ExecuteDelegate has not been set. There is no method to execute for this command.");
}
}
}
我确信这也可用于其他控件,但尚未尝试过。