2014-09-04 4 views
1

У меня есть окна Windows Forms с элементом управления вкладками и один из его вкладчиков ElementHost с ContentControl как дочерний элемент. Этот элемент управления имеет набор привязок ввода, которые работают только тогда, когда у любого дочернего элемента есть фокус ввода, но если фокус потерян, он больше не реагирует. Можно ли определить такие привязки ввода на более высоком уровне в такой ситуации?Как использовать привязки ввода для команд при размещении содержимого WPF в WinForms

+0

Не могли бы вы опубликовать код, чтобы сделать его более конкретным? Как выглядят ваши привязки и каково ваше предложение по размещению их на более высоком уровне (я думаю, это не будет хорошим решением) –

+0

Связывание довольно простое, что-то вроде Demarsch

+0

И если окна образуют контент, как-то получить фокус, эти привязки клавиш больше не могут быть активированы. В WPF вы можете поместить свои привязки в элемент Window, и все будет работать. – Demarsch

ответ

2

Одним из решений может быть передача (туннель) клавиатуры и/или событий мыши из Win Forms на хост WPF. Я сделал следующее доказательство концепции. Он работает, но имеет ограничения и требует больше работы. Сначала вам понадобится класс, полученный от ElementHost. Вы должны использовать его в своем приложении вместо стандартного ElementHost. Этот новый пользовательский класс будет иметь только один дополнительный метод: ProcessWinFormsKeys, который будет сопоставлять определенные ключи WinForms тем, которые используются WPF. Затем он найдет правильную привязку ввода и выполнит ее.

public class CustomElementHost : ElementHost 
    { 
     public void ProcessWinFormsKeys(Keys keys, Keys modifiers) 
     { 
      var key = KeyInterop.KeyFromVirtualKey((int)keys); 

      var modifier = System.Windows.Input.ModifierKeys.None; 

      if ((modifiers & Keys.Control) != 0) 
       modifier |= System.Windows.Input.ModifierKeys.Control; 

      if ((modifiers & Keys.Shift) != 0) 
       modifier |= System.Windows.Input.ModifierKeys.Shift; 

      if ((modifiers & Keys.Alt) != 0) 
       modifier |= System.Windows.Input.ModifierKeys.Alt; 

      foreach (InputBinding inputBinding in Child.InputBindings) 
      { 
       var keyGesture = inputBinding.Gesture as KeyGesture; 

       if (keyGesture == null) 
        continue; 

       if(keyGesture.Key == key && keyGesture.Modifiers == modifier) 
        if(inputBinding.Command.CanExecute(inputBinding.CommandParameter)) 
         inputBinding.Command.Execute(inputBinding.CommandParameter); 
      } 
     } 
    } 

Затем в формы, который содержит экземпляр CustomElementHost вы должны подписаться KeyDown события и вызвать ProcessWinFormsKeys метода внутри обработчика:

public Form() 
    { 
     InitializeComponent(); 

     KeyPreview = true; 
     KeyDown += Form_KeyDown; 
     ... 
    } 

    void Form_KeyDown(object sender, KeyEventArgs e) 
    { 
     elementHost.ProcessWinFormsKeys(e.KeyCode, e.Modifiers); 
    } 

Другим решением может быть используйте глобальные горячие клавиши. Это потребует использования функции RegisterHotKey от user32.dll. Тем не менее, я не уверен, будет ли он работать с ElementHost. Если вы хотите попробовать, есть несколько вопросов о stackoverflow и десятках статей в Интернете.