Ich entdecke ein sehr seltsames Verhalten von WindowsFormsHost
in WPF. Ich finde, wenn ein WPF-Steuerelement WindowsFormsHost
nicht als untergeordnetes Steuerelement hat, dann IsKeyboardFocusWithinChanged
wird ordnungsgemäß ausgelöst - es wird ausgelöst, wenn das WPF-Steuerelement Fokuspunkte erreicht oder verliert und die Variable IsKeyboardFocusWithin
wie erwartet umgeschaltet wird ( true
, wenn das Steuerelement ansteigt Fokus, false
, wenn der Fokus verloren geht).
Aber, wenn ich ein WindowsFormHost
in WPF hosste, wird das IsKeyboardFocusWithinChanged
-Ereignis nach einer kurzen Weile nicht mehr sowohl für das WPF-Mutter-Steuerelement als auch für das WindowsFormHost
-Unter-Steuerelement ausgelöst.
Ich kann in MSDN-Dokumentation oder SO warum nicht finden, keinen Grund?
Das ist mein Code:
MainWindow.xaml
%Vor%MainWindow.xaml.cs
%Vor% Wenn die Zeilen mit WindowsFormHost
auskommentiert sind, dann ist IsKeyboardFocusWithin
true
, wenn das Steuerelement den Fokus erhält, und false
, wenn das Steuerelement den Fokus verliert.
Wenn die Zeilen mit WindowsFormHost
vorhanden sind, dann ist IsKeyboardFocusWithin
true
, bis ich auf das Steuerelement klicke und dann host.IsKeyboardFocusWithin
wird false
und IsKeyboardFocusWithin
wird auch false
und dann, egal was ich tue, wird IsKeyboardFocusWithinChanged
event nie wieder gefeuert.
Optimierte vorherige Lösung zur Unterstützung mehrerer WindowsFormsHost
-Elemente in Window
. Aktualisierter Stil, um fokussiertes Steuerelement mit grünem Rand hervorzuheben, wenn die IsKeyboardFocusWithin
-Eigenschaft true
ist.
MainWindow.xaml
%Vor%MainWindow.xaml.cs
%Vor%Screenshot
Wie Hans Passant im Kommentar erwähnt hat, wird dieses Verhalten dadurch verursacht, dass die WindowsFormsHost
und die MaskedTextBox
unterschiedliche Hwnd (s) haben.
Wenn Sie das erste Mal auf das Host-Steuerelement klicken, wird das untergeordnete Steuerelement den Fokus erhalten, und IsKeyboardFocusedWithin wird ordnungsgemäß festgelegt. Sobald das untergeordnete Steuerelement jedoch den Fokus erhält, bemerkt das Betriebssystem den Unterschied in Hwnd und sendet die Nachricht kill-focus an das WPF-Fenster, wodurch wiederum IsKeyboardFocusedWithin als false festgelegt wird.
Was Sie tun können, ist, einen WndProc
Hook zu Ihrem WPF-Hauptfenster hinzuzufügen und die Nachricht kill-focus zu unterdrücken - nur wenn der IsKeyboardFocusedWithin
-Wert des Host-Controls wahr ist.
Es gibt jedoch einen Nebeneffekt: Wenn Sie vom WPF-Fenster weg wechseln, bleibt der IsKeyboardFocusedWithin
-Wert des Host-Steuerelements möglicherweise wahr. Um dies zu beheben, können Sie einen einfachen Traversaltrick verwenden, um den Fokus zu verschieben, wenn eine mit Fenster versehene Nachricht gesendet wird, und daher die Eigenschaft IsKeyboardFocusedWithin entsprechend dem aktuellen Status aktualisiert hat.
Quellcodebeispiel: Ich habe ein StackPanel anstelle eines Rasters verwendet, um die TextBox (s) anzuzeigen
%Vor%Und das Ergebnis wird so aussehen:
Mit Fokus
Ohne Fokus
Tags und Links wpf c# windowsformshost