ここでは、WPF と Windows フォームの両方のテクノロジを使用するハイブリッド アプリケーションを作成するときに発生する可能性のある一般的な問題について説明します。
コントロールの重複
コントロールが意図したように重ならない場合があります。Windows フォームは、コントロールごとに異なる HWND を使用します。WPF は、ページ上のすべてのコンテンツに 1 つの HWND を使用します。このような実装の違いにより、意図したものとは異なる重なり方になります。
WPF でホストされている Windows フォーム コントロールは、常に WPF コンテンツの一番上に表示されます。
ElementHost コントロールでホストされている WPF コンテンツは、ElementHost コントロールの z オーダーで表示されます。ElementHost コントロールを重ねることはできますが、ホストされている WPF コンテンツは相互に結合または対話しません。
子プロパティ
WindowsFormsHost クラスおよび ElementHost クラスがホストできる子コントロールまたは要素は 1 つだけです。複数のコントロールまたは要素をホストするには、子コンテンツとしてコンテナを使用する必要があります。たとえば、Windows フォームのボタン コントロールとチェック ボックス コントロールを System.Windows.Forms.Panel コントロールに追加し、パネルを WindowsFormsHost コントロールの Child プロパティに割り当てることはできます。しかし、ボタン コントロールとチェック ボックス コントロールを個別に同じ WindowsFormsHost コントロールに追加することはできません。
スケーリング
WPF と Windows フォームでは、スケーリング モデルが異なります。WPF のスケーリング変換には、Windows フォーム コントロールに対して意味のあるものと意味のないものがあります。たとえば、Windows フォーム コントロールの 0 へのスケーリングは機能しますが、同じコントロールを 0 以外の値にスケーリングして戻そうとしても、コントロールのサイズは 0 のままです。詳細については、「WindowsFormsHost 要素のレイアウトに関する考慮事項」を参照してください。
アダプタ
WindowsFormsHost クラスと ElementHost クラスには非表示のコンテナが含まれるため、これらを使用する際には混乱が生じる場合があります。WindowsFormsHost クラスと ElementHost クラスはどちらもアダプタと呼ばれる非表示のコンテナを持っており、コンテンツをホストするために使用します。WindowsFormsHost 要素の場合、アダプタは System.Windows.Forms.ContainerControl クラスから派生します。ElementHost コントロールの場合、アダプタは DockPanel 要素から派生します。このコンテナについては、相互運用性に関する他のトピックでアダプタに関する説明を参照してください。
入れ子
ElementHost コントロールの内部への WindowsFormsHost 要素の入れ子は、サポートされていません。WindowsFormsHost 要素の内部への ElementHost コントロールの入れ子も、サポートされていません。
フォーカス
WPF と Windows フォームではフォーカスの動作が異なり、ハイブリッド アプリケーションではフォーカスに関する問題が発生する可能性があります。たとえば、WindowsFormsHost 要素の内部にフォーカスがある場合、ページを最小化して元に戻すと、またはモーダル ダイアログ ボックスを表示すると、WindowsFormsHost 要素の内部のフォーカスが失われる可能性があります。WindowsFormsHost 要素はまだフォーカスを保持していますが、内部のコントロールはフォーカスを失う場合があります。
データの検証も、フォーカスによって影響されます。検証は WindowsFormsHost 要素の中では機能しますが、WindowsFormsHost 要素から外へ Tab キーで移動する場合や、2 つの異なる WindowsFormsHost 要素の間では、検証が機能しません。
プロパティの割り当て
一部のプロパティの割り当てでは、WPF テクノロジと Windows フォーム テクノロジの間の異なる実装をブリッジするために、広範な解釈が必要になります。プロパティの割り当てを使用すると、フォント、色、およびその他のプロパティの変更にコードで対応できます。一般に、プロパティの割り当ては、PropertyChanged イベントまたは OnPropertyChanged 呼び出しをリッスンし、子コントロールまたはそのアダプタで適切なプロパティを設定することで機能します。詳細については、「Windows フォームと WPF プロパティの割り当て」を参照してください。
ホストされるコンテンツでのレイアウト関連のプロパティ
System.Windows.Forms.Integration.WindowsFormsHost.Child プロパティまたは System.Windows.Forms.Integration.ElementHost.Child プロパティを割り当てると、ホストされるコンテンツで複数のレイアウト関連プロパティが自動的に設定されます。これらのコンテンツ プロパティを変更すると、予期しないレイアウト動作が発生する場合があります。
ホストされるコンテンツは、WindowsFormsHost および親の ElementHost を埋めるようにドッキングされます。この動作を有効にするため、子プロパティを設定すると複数のプロパティが設定されます。ElementHost クラスおよび WindowsFormsHost クラスによって設定されるコンテンツ プロパティを次の表に示します。
| ホスト クラス | コンテンツ プロパティ |
|---|---|
| ElementHost | |
| WindowsFormsHost |
ホストされるコンテンツで、これらのプロパティを直接設定しないでください。詳細については、「WindowsFormsHost 要素のレイアウトに関する考慮事項」を参照してください。
ナビゲーション アプリケーション
ナビゲーション アプリケーションが、ユーザーの状態を保持しない場合があります。WindowsFormsHost 要素は、ナビゲーション アプリケーションで使用されると、コントロールを再作成します。ユーザーが WindowsFormsHost 要素をホストするページから移動した後、そのページに戻ると、子コントロールの再作成が発生します。ユーザーがそれまでに入力したコンテンツは失われます。
メッセージ ループの相互運用
Windows フォームのメッセージ ループを使用するとき、メッセージが意図したように処理されない場合があります。EnableWindowsFormsInterop メソッドは WindowsFormsHost コンストラクタによって呼び出されます。このメソッドは、WPF のメッセージ ループにメッセージ フィルタを追加します。このフィルタは、System.Windows.Forms.Control がメッセージの送信先であった場合は System.Windows.Forms.Control.PreProcessMessage(System.Windows.Forms.Message) メソッドを呼び出し、メッセージを変換およびディスパッチします。
System.Windows.Forms.Application.Run で Windows フォームのメッセージ ループ内の Window を表示した場合、EnableModelessKeyboardInterop メソッドを呼び出さない限り、何も入力できません。EnableModelessKeyboardInterop メソッドは、Window を受け取り、キー関連のメッセージ再ルーティングする System.Windows.Forms.IMessageFilter を WPF のメッセージ ループに追加します。詳細については、「Windows フォームと WPF の相互運用性入力アーキテクチャ」を参照してください。
不透明度とレイヤ表示
HwndHost クラスは、レイヤ表示をサポートしません。つまり、WindowsFormsHost 要素で Opacity プロパティを設定しても何の効果もなく、AllowsTransparency が true に設定されている他の WPF ウィンドウとのブレンド操作は行われません。
破棄
クラスを適切に破棄しないと、リソースがリークする可能性があります。ハイブリッド アプリケーションでは、WindowsFormsHost クラスと ElementHost クラスを確実に破棄してください。そうしないと、リソースがリークする可能性があります。Windows フォームは、モーダルではない親の Form が閉じると、ElementHost コントロールを破棄します。WPF は、アプリケーションがシャットダウンすると WindowsFormsHost 要素を破棄します。Windows フォームのメッセージ ループ内の Window で WindowsFormsHost 要素を表示する場合があります。この場合は、アプリケーションがシャットダウンしているという通知をコードが受け取らない可能性があります。
visual スタイルの有効化
Windows フォーム コントロールで Microsoft Windows XP の視覚スタイルが有効にならない場合があります。Windows フォーム アプリケーションのテンプレートでは、System.Windows.Forms.Application.EnableVisualStyles メソッドが呼び出されます。このメソッドは既定では呼び出されませんが、Comctl32.dll のバージョン 6.0 が利用できる場合は、Visual Studio を使用してプロジェクトを作成すると、コントロールに対する Microsoft Windows XP の視覚スタイルを取得します。スレッドでハンドルが作成される前に、EnableVisualStyles メソッドを呼び出す必要があります。詳細については、「方法 : ハイブリッド アプリケーションで視覚スタイルを有効にする」を参照してください。
ライセンスされたコントロール
メッセージ ボックスでライセンス情報を表示するライセンスされた Windows フォーム コントロールは、ハイブリッド アプリケーションでは予期しない動作を示す場合があります。ライセンスされたコントロールの中には、ハンドルの作成に対してダイアログ ボックスを表示するものがあります。たとえば、ライセンスされたコントロールは、ライセンスが必要なことや、コントロールの残りの試用ライセンスが 3 つであることなどを、ユーザーに通知する場合があります。
WindowsFormsHost 要素は HwndHost クラスから派生し、子コントロールのハンドルは BuildWindowCore メソッドの内部で作成されます。HwndHost クラスは BuildWindowCore メソッドでのメッセージの処理を許可しませんが、ダイアログ ボックスを表示するとメッセージが送信されます。このライセンス シナリオを有効にするには、WindowsFormsHost 要素の子としてコントロールを割り当てる前に、コントロールで System.Windows.Forms.Control.CreateControl メソッドを呼び出します。