私が頼んだことをする方法はありません。しかし、私たちは回避策を見つけました。Windowsフォーム内にxamlウィンドウを「単純に」埋め込む。
私たちが従った手順は次のとおりです。
1 - プロジェクトに Windows フォームを追加します。
2 - app.xaml を削除し、新しいフォームをアプリケーションのエントリ ポイントにします。
3 - main.xaml の hwnd が必要なので、このプロップをそのコード ビハインドに追加しました
public IntPtr Hwnd
{
get { return new WindowInteropHelper(this).Handle; }
}
4 - 次に、フォームのコンストラクターから wpf ウィンドウ クラスのインスタンスを作成します。
private Main app;
public ContainerForm()
{
InitializeComponent();
app = new Main();
ElementHost.EnableModelessKeyboardInterop(app);
}
私たちが必要としていた
ElementHost.EnableModelessKeyboardInterop(app);
すべてのキーボード入力を Windows フォームから xaml ウィンドウに渡すため
5 - ここで、xpf ウィンドウを winform に結合します。これを行うには、Windows Api を使用する必要があり、フォームの OnShow イベントで行います (理由は後で説明します)。
[DllImport("user32.dll", SetLastError = true)]
private static extern long SetFocus(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
[DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)]
private static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong);
private const int GWL_STYLE = (-16);
private const int WS_VISIBLE = 0x10000000;
private void ContainerForm_Shown(object sender, EventArgs e)
{
app.Show();
SetParent(app.Hwnd, this.Handle);
SetWindowLong(app.Hwnd, GWL_STYLE, WS_VISIBLE);
MoveWindow(app.Hwnd, 0, 0, this.Width, this.Height, true);
SetFocus(app.Hwnd);
}
と
SetParent(app.Hwnd, this.Handle);
wo do the magic, then with
SetWindowLong(app.Hwnd, GWL_STYLE, WS_VISIBLE);
wpf ウィンドウからすべてのクロムを削除します (ウィンドウが境界線なしで定義されていても境界線があります。理由は聞かないでください)。
次に、wpf ウィンドウが winform のすべてのクライアント領域を埋めるようにします。
MoveWindow(app.Hwnd, 0, 0, this.Width, this.Height, true);
次に、wpf ウィンドウにフォーカスします
SetFocus(app.Hwnd);
それが、ショーイベントですべてを行う理由です。フォームのコンストラクターでこれを行うと、winform のメイン ウィンドウがオペレーティング システムからフォーカスを取得したため、wpf ウィンドウはフォーカスを失います。
この時点で他の API 呼び出しを追加する必要がある理由がわかりませんでしたが、それらをコンストラクターに残したままにしておくと、このトリックは機能しませんでした。
とにかく、問題は解決しました;)