2013-07-15 5 views
2

Я разрабатываю приложение MVVM, и я бы хотел создать глобальные ярлыки для моего приложения. Необходимо подключить приложение между модулями. У меня есть главное окно с кодом:WPF ярлык во всем окне

<UserControl.InputBindings> 
    <KeyBinding Command="{Binding ChangeModuleComand}" 
        Key="M" 
        Modifiers="Control"/> 
</UserControl.InputBindings> 

Это работает, когда у меня есть фокус на моем окне,

Но есть проблема, когда я иметь фокус на TextBox в этой UserControl (команда не уволен).

Возможно ли уловить это ключевое давление без большого количества изменений во всем приложении?

А.

+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"); 
    } 
0

Документирование этот ответ для других, так как есть более простой способ сделать это, что редко ссылаются, и не требует касания XAML вообще.

Чтобы связать сочетание клавиш на уровне окна, в конструкторе 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."); 
     } 
    } 
} 

Я уверен, что это может быть использовано и для других элементов управления, но не пробовал.

Смежные вопросы