Windows フォームコントロールを WPF アプリケーションで使う

Last Updated 2011/09/21


Windows フォーム用標準コントロールはたくさんあります。また、すでに Windows フォーム対応のカスタムコントロールを持っている人もいると思います。WPF アプリケーションでもこれらを利用できれば便利ですね。このページではその手順を説明します。


Windows フォームコントロールのほうにあって、WPF コントロールにはないコントロールはたくさんあります。しかし、WPF の手法を使えば、コントロールを自作することはそう難しいことではありません。たとえば、チェックボックス付きのリストボックスである CheckedListBox コントロールであれば簡単に実現できます。つまり、WPF コントロールの中に CheckedListBox コントロールがないからといって、それがただちに Windows フォームアプリケーション開発のほうが容易ということにはなりません。

ともあれ、Windows フォームコントロール(このページでは Button コントロールを取り上げます)を WPF アプリケーションで使う手順を説明します。

  1. 使いたいコントロールのライブラリ(ここでは System.Windows.Forms.dll ファイル)への参照をプロジェクトに追加する
  2. WindowsFormsHost クラスを提供する WindowsFormsIntegration.dll への参照をプロジェクトに追加する(この DLL は私の環境では C:\Windows\Microsoft.NET\Framework\v4.0.20506\WPF にあります)
  3. XAML コードにライブラリの名前空間名を追加する
  4. ツールボックスに WindowsFormsHost コントロールがあるので、これをフォームに貼り付ける(XAML コードを直接書いてもよい)
  5. WindowsFormsHost コントロールの子要素として、使用するコントロールを追加する(追加は直接コードを使って書き込む)
  6. XAML コードで、コントロールの各プロパティやイベントハンドラを設定する
  7. 必要なら、分離コードを書く

 

下図は、WPF アプリケーションに Windows フォームコントロールの Button コントロールを使う例です。上は、WPF の Button コントロールで、下は Windows フォームコントロールの Button コントロールです。見た目の違いを覚えておいてください。

WindowsFormsHost

Windows フォームコントロールを WPF アプリケーションに組み込む XAML コードは以下のとおり。

<Window x:Class="ApplicationTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:winform="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    Title="WindowsFormsHost" Height="300" Width="300" Name="window1"
  >
  <StackPanel Orientation="Vertical">
    <Button Name="button2" Width="150" Height="25" Margin="10" Click="button2_Click">WPF Button(_P)</Button>
    <WindowsFormsHost Width="150" Height="30" Margin="10">
      <winform:Button x:Name="button1" Text="WinForms Button(&amp;W)" BackColor="Gainsboro"
                      Click="Button_Click" KeyDown="button1_KeyDown" />
    </WindowsFormsHost>
  </StackPanel>
</Window>

上記のコードの一部を抜き出して、注意すべき事項について説明します。

<winforms:Button
   x:Name="button1"                   ← Name プロパティは不可、x:Name 属性で指定する
   Text="WinForms Button(&amp;W)" ← Content プロパティではない。また、アクセスキーはアンダースコアではない
   BackColor="Gainsboro"              ← これがないと背景色は白色になる。また、テーマは反映されない
   Click="button1_Click"
   KeyDown="button1_KeyDown"          ← マウスのクリックは可能だが、フォーカスがあるときに [Return] しても Click イベントは発生しない
/>

次に、コントロールの動作を確認するための分離コードを示しますので、実際にテストしてみてください。

private void button1_Click(object sender, EventArgs e)
{
  MessageBox.Show("button1_Click");
}

private void button1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
  this.button1_Click(sender, EventArgs.Empty);
}

private void button2_Click(object sender, RoutedEventArgs e)
{
  MessageBox.Show("button2_Click");
}

上の図を見てのとおり、ボタンの表面色は単色で、Windows Vista/7 のテーマを反映しません

WPF におけるアクセスキーの指定は、アンダースコア "_" ですが、従来どおり、アンパサンド "&" を使います。しかし、"&" は XML 構文の規則に違反する記号なので、"&amp;" を使わなければなりません。

上記のコードでは KeyDown イベントハンドラを設定していますが、これがなくてもマウスによるクリックには反応します。しかし、ボタンにフォーカスがあるときに [Return] キーを押しても反応しません。そこで、ボタンがフォーカスがあるときに [Return] キーを押すと、Click イベントが強制的に発生するようにしました。

もう一つの注意事項は、WindowsFormsHost コントロールには一つの子要素しか配置できません、また子要素のサイズは WindowsFormsHost コントロールの位置とサイズに制約されます。つまり、子要素独自に位置とサイズを指定することはできません。上記の XAML コードを見てのとおり、ボタンのサイズは指定しないかわりに、WindowsFormsHost コントロールのサイズをボタンコントロールのサイズとして設定しています。

ということで、Windows フォームアプリケーションを WPF アプリケーションで使うには制限が多すぎます。テキストエディタコントロールのようにビジュアルな要素の少ないコントロールぐらいしか使えないと思います。WPF はカスタムコントロールを作ることが容易ですから WPF コントロールとして作り直すことをすすめます。

−以上−