Eingabearchitektur für die Interoperabilität zwischen Windows Forms und WPF

Der dialogfähige Betrieb zwischen WPF und Windows Forms setzt voraus, dass in beiden Technologien eine entsprechende Verarbeitung von Tastatureingaben möglich ist. In diesem Thema wird beschrieben, wie diese Technologien die Verarbeitung von Tastatureingaben und -meldungen implementieren, um in Hybridanwendungen einen reibungslosen dialogfähigen Betrieb zu ermöglichen.

Dieses Thema enthält folgende Unterabschnitte:

  • Nicht modale Formulare und Dialogfelder

  • Verarbeitung von WindowsFormsHost-Tastatureingaben und -meldungen

  • Verarbeitung von ElementHost-Tastatureingaben und -meldungen

Nicht modale Formulare und Dialogfelder

Rufen Sie die EnableWindowsFormsInterop-Methode für das WindowsFormsHost-Element auf, um ein nicht modales Formular oder Dialogfeld in einer WPF-basierten Anwendung zu öffnen.

Rufen Sie die EnableModelessKeyboardInterop-Methode für das ElementHost-Steuerelement auf, um eine nicht modale WPF-Seite in einer Windows Forms-basierten Anwendung zu öffnen.

Verarbeitung von WindowsFormsHost-Tastatureingaben und -meldungen

Beim Hosten durch eine WPF-basierte Anwendung erfolgt die Verarbeitung von Windows Forms-Tastatureingaben und -meldungen wie folgt:

  • Die WindowsFormsHost-Klasse bezieht Meldungen aus der WPF-Meldungsschleife, die von der ComponentDispatcher-Klasse implementiert wird.

  • Die WindowsFormsHost-Klasse erstellt eine Windows Forms-Ersatzmeldungschleife, um sicherzustellen, dass die normale Verarbeitung von Windows Forms-Tastatureingaben erfolgt.

  • Die WindowsFormsHost-Klasse implementiert die IKeyboardInputSink-Schnittstelle zum Koordinieren der Fokusverwaltung mit WPF.

  • Die WindowsFormsHost-Steuerelemente registrieren sich selbst und starten ihre Meldungsschleifen.

In den folgenden Abschnitten werden diese Teile des Prozesses näher beschrieben.

Beziehen von Meldungen aus der WPF-Meldungsschleife

Die ComponentDispatcher-Klasse implementiert den Meldungsschleifen-Manager für WPF. Die ComponentDispatcher-Klasse stellt Hooks für externe Clients bereit, mit denen Sie Meldungen filtern können, ehe WPF sie verarbeitet.

Die Implementierung des dialogfähigen Betriebs behandelt das ComponentDispatcher.ThreadFilterMessage-Ereignis, durch das Windows Forms-Steuerelemente Meldungen vor WPF-Steuerelementen verarbeiten können.

Windows Forms-Ersatzmeldungsschleife

Standardmäßig enthält die System.Windows.Forms.Application-Klasse die primäre Meldungsschleife für Windows Forms-Anwendungen. Während des dialogfähigen Betriebs verarbeitet die Windows Forms-Meldungsschleife keine Meldungen. Daher muss diese Logik reproduziert werden. Der Handler für das ComponentDispatcher.ThreadFilterMessage-Ereignis führt die folgenden Schritte aus:

  1. Filtert die Meldung mithilfe der IMessageFilter-Schnittstelle.

  2. Aufruf der Control.PreProcessMessage-Methode.

  3. Übersetzt und versendet die Meldung, falls erforderlich.

  4. Übergibt die Meldung an das hostende Steuerelement, wenn keine anderen Steuerelemente die Meldung verarbeiten.

IKeyboardInputSink-Implementierung

Die Ersatzmeldungsschleife behandelt die Verwaltung von Tastatureingaben. Daher ist die IKeyboardInputSink.TabInto-Methode der einzige IKeyboardInputSink-Member, der eine Implementierung in der WindowsFormsHost-Klasse erfordert.

Standardmäßig gibt die HwndHost-Klasse für ihre IKeyboardInputSink.TabInto-Implementierung false zurück. Dies verhindert, dass Sie mit der Tabulatortaste von einem WPF-Steuerelement zu einem Windows Forms-Steuerelement wechseln.

Die WindowsFormsHost-Implementierung der IKeyboardInputSink.TabInto-Methode führt die folgenden Schritte aus:

  1. Ermittelt das erste oder letzte Windows Forms-Steuerelement, das im WindowsFormsHost-Steuerelement enthalten ist und den Fokus erhalten kann. Die Wahl des Steuerelements hängt von Informationen zum Durchlauf ab.

  2. Legt den Fokus auf das Steuerelement fest und gibt true zurück.

  3. Gibt false zurück, wenn kein Steuerelement den Fokus erhalten kann.

WindowsFormsHost-Registrierung

Wenn der Fensterhandle für ein WindowsFormsHost-Steuerelement erstellt wird, ruft das WindowsFormsHost-Steuerelement eine interne statische Methode auf, die seine Anwesenheit für die Meldungsschleife registriert.

Während der Registrierung prüft das WindowsFormsHost-Steuerelement die Meldungsschleife. Wenn die Meldungsschleife noch nicht gestartet wurde, wird der ComponentDispatcher.ThreadFilterMessage-Ereignishandler erstellt. Die Meldungsschleife gilt als aktiv, wenn der ComponentDispatcher.ThreadFilterMessage-Ereignishandler angefügt ist.

Wenn der Fensterhandle zerstört wird, entfernt sich das WindowsFormsHost-Steuerelement selbst aus der Registrierung.

Verarbeitung von ElementHost-Tastatureingaben und -meldungen

Beim Hosten durch eine Windows Forms-basierte Anwendung erfolgt die Verarbeitung von WPF-Tastatureingaben und -meldungen wie folgt:

In den folgenden Abschnitten werden diese Teile ausführlicher beschrieben.

Schnittstellenimplementierungen

In Windows Forms werden Tastaturmeldungen an den Fensterhandle des Steuerelements weitergeleitet, das den Fokus hat. Im ElementHost-Steuerelement werden diese Meldungen an das gehostete Element weitergeleitet. Zu diesem Zweck bietet das ElementHost-Steuerelement eine HwndSource-Instanz. Wenn das ElementHost-Steuerelement den Fokus hat, leitet die HwndSource-Instanz die meisten Tastatureingaben so weiter, dass sie von der WPF InputManager-Klasse verarbeitet werden können.

Die HwndSource-Klasse implementiert die Schnittstellen IKeyboardInputSink und IKeyboardInputSite.

Der dialogfähige Betrieb der Tastatur beruht auf der Implementierung der OnNoMoreTabStops-Methode zur Behandlung von Eingaben mit TAB- und Pfeiltasten, die den Fokus aus gehosteten Elementen herausbewegen.

Wechseln mit der Tabulatortaste und Pfeiltasten

Die Windows Forms-Auswahllogik ist den IKeyboardInputSink.TabInto- und OnNoMoreTabStops-Methoden zugeordnet, um die TAB- und Pfeiltastennavigation zu implementieren. Durch Überschreiben der Select-Methode wird diese Zuordnung erreicht.

Befehls- und Dialogfeldtasten

Um WPF die erste Möglichkeit zu geben, Befehls- und Dialogfeldtasten zu verarbeiten, ist die Vorverarbeitung von Windows Forms-Befehlen mit der TranslateAccelerator-Methode verbunden. Durch Überschreiben der Control.ProcessCmdKey-Methode werden die beiden Technologien verbunden.

Mit der TranslateAccelerator-Methode können die gehosteten Elemente jede beliebige Tastenmeldung verarbeiten, z. B. WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN oder WM_SYSKEYUP, einschließlich Befehlstasten, wie TAB-, EINGABE-, ESC- und Pfeiltasten. Wenn eine Tastenmeldung nicht bearbeitet wird, wird sie in der Windows Forms-Vorgängerhierarchie zur Bearbeitung nach oben gesendet.

Beschleunigerverarbeitung

Um Beschleuniger ordnungsgemäß zu verarbeiten, muss die Windows Forms-Beschleunigerverarbeitung mit der AccessKeyManager-Klasse von WPF verbunden sein. Außerdem müssen alle WM_CHAR-Meldungen ordnungsgemäß an gehostete Elemente weitergeleitet werden.

Da die standardmäßige HwndSource-Implementierung der TranslateChar-Methode false zurückgibt, werden WM_CHAR-Meldungen nach der folgenden Logik verarbeitet:

  • Die Control.IsInputChar-Methode wird überschrieben, um sicherzustellen, dass alle WM_CHAR-Meldungen an gehostete Elemente weitergeleitet werden.

  • Wenn die ALT-TASTE gedrückt wird, ist die Meldung WM_SYSCHAR. Windows Forms verarbeitet diese Nachricht nicht durch die IsInputChar-Methode vor. Daher wird die ProcessMnemonic-Methode so überschrieben, dass AccessKeyManager von WPF nach einem registrierten Beschleuniger abgefragt wird. Wenn ein registrierter Beschleuniger gefunden wird, wird er von AccessKeyManager verarbeitet.

  • Wenn die ALT-Taste nicht gedrückt wird, verarbeitet die WPF-Klasse InputManager die unbehandelte Eingabe. Wenn es sich bei der Eingabe um einen Beschleuniger handelt, wird er von AccessKeyManager verarbeitet. Das PostProcessInput-Ereignis wird für WM_CHAR-Meldungen behandelt, die nicht verarbeitet wurden.

Wenn der Benutzer die ALT-TASTE drückt, werden visuelle Hinweise des Beschleunigers auf dem gesamten Formular angezeigt. Um dieses Verhalten zu unterstützen, erhalten alle ElementHost-Steuerelemente auf dem aktiven Formular WM_SYSKEYDOWN-Meldungen unabhängig davon, welches Steuerelement den Fokus hat.

Meldungen werden nur an ElementHost-Steuerelemente im aktiven Formular gesendet.

Weitere Informationen