執筆者: 大野 元久

動作確認環境: Visual Studio 2008、Visual Studio 2010

更新日: 2010 年 11 月 26 日

WPF には、多数の機能的なコントロールが用意されている一方、Windows フ ォームで使っていたコントロールがそのまま使えるわけではありません。また、Windows フォーム用に作られた外部コントロールを使うこともできません。しかし、WPF は Windows フォームと同じ .NET Framework を基盤としており、WPF には Windows フォーム用のコントロールを再利用するために WindowsFormsHost というコントロールが用意されています。

Code [XAML]

<Window x:Class="WpfWFApplication.MainWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
       xmlns:self="clr-namespace: WpfWFApplication"
       Title="MainWindow" Height="350" Width="525">
   <Grid>
       <Grid.ColumnDefinitions>
           <ColumnDefinition Width="Auto" />
           <ColumnDefinition Width="*" />
       </Grid.ColumnDefinitions>
       <Grid.RowDefinitions>
           <RowDefinition Height="Auto" />
           <RowDefinition Height="Auto" />
           <RowDefinition Height="*" />
       </Grid.RowDefinitions>

       <Label Grid.Column="0" Grid.Row="0" Content="Date" />
       <WindowsFormsHost Grid.Column="1" Grid.Row="0">
           <wf:MaskedTextBox x:Name="maskedText1" Mask="0000/00/00" />
       </WindowsFormsHost>

       <Label Grid.Column="0" Grid.Row="1" Content="Time" />
       <WindowsFormsHost Grid.Column="1" Grid.Row="1">

       </WindowsFormsHost>
       <WindowsFormsHost Grid.Column="1" Grid.Row="2">
           <self:MyUserControl x:Name="mycontrol1" />
       </WindowsFormsHost>
   </Grid>
</Window>

実行結果

ポイント

WPF アプリケーションで Windows フォーム用のコントロールを使うためには、まずプロジェクトの参照設定で Windows フォーム用のアセンブリを追加しなければなりません。ソリューション エクスプローラーでプロジェクト名を右クリックし、[参照の追加] メニューを呼び出します。ここで次の図のように System.Windows.Forms を追加します。

また、WindowsFormsHost は WPF 用のコントロールなのでツールボックスに表示されていますが、Windows フォーム用のコントロールはツールボックスには表示されません。このため、XAML を直接編集する必要があります。Window クラスの定義において、Windows フォーム用のアセンブリのための名前空間を次のように記述します。

       xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

これで、タグ名に名前空間 wf を指定することで、Windows フォーム用のコントロールを使えるようになります。たとえば、以下のコードは WindowsFormsHost に MaskedTextBox (入力マスク付きの TextBox) を配置しています。

       <WindowsFormsHost Grid.Column="1" Grid.Row="0">
           <wf:MaskedTextBox x:Name="maskedText1" Mask="0000/00/00" />
       </WindowsFormsHost>

WindowsFormsHost が保持できるものは「1 つのコントロール (Control)」であることに注意してください。たとえば、Timer のように Control ではなく Component から継承しているもの (実行時に表示されなくなるコンポーネント) は配置できません。また、WindowsFormsHost はデザイン画面では指定されたコントロールを表示しません。

WindowsFormsHost は、基本的に Control から継承したものであれば配置できるので、Windows フォーム用に作成したユーザー コントロールを配置することもできます。ここでは、次のような MyUserControl を作成しています。

ユーザー コントロールを配置する場合、その存在場所、つまり自分自身のアセンブリを XAML 側で指定する必要があります。Window クラスの定義における次の指定は、自分自身のアセンブリ (実行ファイル名) を self として参照するものです。

       xmlns:self="clr-namespace: WpfWFApplication"

これにより、次のような記述で MyUserControl というユーザー コントロールを WindwsFormsHost で配置できます。

       <WindowsFormsHost Grid.Column="1" Grid.Row="2">
           <self:MyUserControl x:Name="mycontrol1" />
       </WindowsFormsHost>

なお、通常は WPF の要素は WPF 自身が描画しますが、Windows フォーム用のコントロールは Windows 自身のコントロールとして描画されます。このため、Opacity (半透明)、Effect (ぼかし効果や影など) といった WPF にしかできない表現、Viewport2DVisual3D を使った 3D 空間での利用などは、Windows フォーム用のコントロールには適用できません。

また、それぞれのコントロールは独立した WindowsFormsHost に配置されるため、コンテナ コントロールを使った関係を利用することはできません。たとえば、ラジオボタンを個々の WindowsFormsHost コントロールを使って配置すると、それぞれ独立したグループに属するため、ラジオボタンとしての機能が損なわれます。また、イベントは WPF コントロールのようなルーティング イベントではありません。

WindowsFormsHost は、Windows フォーム コントロールを配置できますが、WPF の特長を追加できるわけではないことに注意し、できるだけ限定的に使うようにしてください。

WindowsFormsHost の詳細については「WindowsFormsHost クラス」を参照してください。


Code Recipe Code Recipe

ページのトップへ