WPF Window を Windows フォームから起動した場合の落とし穴

現行プロジェクトの一部の画面を試験的に WPF に置き換えているのですが、Windows フォームから起動した WPF Window の TextBox に、半角文字が全く入力できないという問題が発生しました。IME が ON なら大丈夫。ただし IME がオフの場合、キーボードを押しまくっても、うんともすんともいいません。('A`)


再現手順

まず、WindowsForms アプリケーションのプロジェクトを作成します。次に、ソリューションに WPF アプリケーションのプロジェクトを追加。Window には TextBox を追加しときます。

WindowsForms のプロジェクトの参照設定に、後から追加した WPF アプリケーションと PresentationFramework.dll を追加。Form に Button を貼りつけて、イベントを実装します。

Imports WpfApplication1

Public Class Form1

        Private Sub Button1_Click(
                ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

                Dim window As New MainWindow()
                window.Show()

        End Sub

End Class

Window フォームから WPF Window を起動し、TextBox に何でもいいから入力してみて下さい。IME が ON なら入力できますが、IME を OFF にすると、スペースやバックスペース・Deleteキー以外反応しなくなります。

解決方法

以下の資料を読むと、WindowForms と WPF ではメッセージに関するアーキテクチャがかなり異なるため、そのままでは正常に運用できないようですね。

Windows フォームと WPF の相互運用性入力アーキテクチャ


そこで Window フォームから WPF Window を起動する場合、ElementHost.EnableModelessKeyboardInterop メソッドを使えばいいとのことです。逆の場合・・・WPF Window から Windowsフォームを起動するなら WindowsFormsHost.EnableWindowsFormsInterop メソッドを使うようです。

以下対処したコードです。これで TextBox に正常に入力できるようになりました。なお Window フォームプロジェクトの参照設定に WindowsFormsIntegration.dll を追加する必要があります。ご注意を。

Imports WpfApplication1
Imports System.Windows.Forms.Integration

Public Class Form1

        Private Sub Button1_Click(
                ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

                Dim window As New MainWindow()
                ElementHost.EnableModelessKeyboardInterop(window)
                window.Show()

        End Sub

End Class