■ はじめに
.NET Framework 3.0 から登場した WPF はまだまだ新しい技術です。事例も少ないことから、導入に踏み切れない方もいらっしゃるかもしれません。そんな方々のために部分的に WPF を試すことができる「Windows フォームから WPF を利用する」方法と、逆に既存資産を活かすための「WPF から Windows フォームコントロールを利用する」方法について、前後編の 2 回に分けて説明します。
■ Windows フォームに WPF コントロールを組み込む
従来の開発手法やフレームワーク、標準化の実績を考えると、大部分の開発は実績のある Windows フォームコントロールで行いたい、しかし、部分的には WPF の技術も利用したいと考えるケースもあるかと思います。
このような場合に、Windows フォームでは WPF コントロールを組み込むことが可能です。このアプローチによるメリットは次の通りです。
・従来の開発手法やフレームワーク、標準化の実績をまだまだ活用できる。
・Windows フォームでは実現が難しい機能、表現を WPF コントロールを用いて実現できる。
● ElementHost コントロール
では、実際に WPF を Windows フォームに組み込むためにはどうしたらよいのでしょうか。それにはここでご紹介する ElementHost コントロールを使う必要があります。この ElementHost コントロールは名前空間System.Windows.Forms.Integration 配下に含まれるコントロールです。
ElementHost クラス
< http://msdn.microsoft.com/ja-jp/library/system.windows.forms.integration.elementhost(VS.80).aspx >
● サンプル
ここではサンプルとしてシステムのログイン画面を想定した ID とパスワードの入力コントロールを Blend で作成してみます。Blend お得意のアニメーション効果も設定してみましょう。
今回は WPF ユーザコントロールを作成しますので、プロジェクトの種類は「WPF コントロールライブラリ」を選択し、名前に「WPFInputControlLibrary」と入力しました。
【Blend での UserControl の作成】

ウィンドウでは ellipse(楕円)とラベル、テキストボックスを組み合わせコントロール「LoginControl」を作成し、コントロールの Load イベントでは ellipse に対し、グラデーションがかかるように Storyboard を設定しました。
【LoginControl の作成】

ここからは Visual Studio の出番です。新しいプロジェクトを「Windows フォームアプリケーション」で作成します。ここではプロジェクト名を「ElementHostSample」としました。
【Windows フォームアプリケーションプロジェクトの作成】

プロジェクトが作成できたら先ほど Blend で作成した「WPFInputControlLibrary」に対し、プロジェクト参照を設定します。また、追加したプロジェクトの中から LoginControl.xaml.vb を開き、WPF ユーザコントロールに対し、外部に Login プロパティを公開するため ID とパスワードのテキストボックスからそれぞれ Text プロパティを作成します。
LoginControl へのプロパティの実装(上が VisualBasic、下が C#)
Imports System
Imports System.Collections.Generic
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Data
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Media.Imaging
Imports System.Windows.Navigation
Imports System.Windows.Shapes
Partial Public Class LoginControl
Public Sub New()
MyBase.New()
Me.InitializeComponent()
' オブジェクト作成に必要なコードをこの点の下に挿入します。
End Sub
'WPF コントロールの ID テキストボックスを公開します。
Public Property ID() As String
Get
Return Me.txtID.Text
End Get
Set(ByVal value As String)
Me.txtID.Text = value
End Set
End Property
'WPF コントロールのパスワードテキストボックスを公開します。
Public Property Password() As String
Get
Return Me.txtPassword.Password
End Get
Set(ByVal value As String)
Me.txtPassword.Password = value
End Set
End Property
End Class
--------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfInputControlLibrary
{
public partial class LoginControl
{
public LoginControl()
{
this.InitializeComponent();
}
// WPF コントロールの ID テキストボックスを公開します。
public string ID
{
get
{
return this.txtID.Text;
}
set
{
this.txtID.Text = value;
}
}
// WPF コントロールのパスワードテキストボックスを公開します。
public string Password
{
get
{
return this.txtPassword.Password;
}
set
{
this.txtPassword.Password = value;
}
}
}
}
実装が終わったら Windows フォームへ WPF ユーザコントロールを配置します。Form1.vb を開き、ツールボックスから Windows フォームコントロールのボタンと作成した WPF ユーザコントロールの LoginControl を Form 上に配置します。
【Windows フォームへの WPF コントロールの配置】

配置時には Form 上に直接 LoginControl を配置しているように見えますが、実際には Form 上には ElementHost が配置され、ElementHost の Child プロパティに LoginControl が配置されます。
【Form1 のドキュメントアウトラインと ElementHost のプロパティ】

配置が終わったら今度はボタン押下時のイベント処理を実装します。ここでは WPF コントロール上の ID テキストボックスとパスワードテキストボックスをメッセージボックスで表示するように実装を行いました。
Windows フォームでのイベントハンドリングの実装(上が VisualBasic、下が C#)
Public Class Form1
' ボタン押下時のイベントを定義します。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnWindowsControl.Click
MessageBox.Show("入力された ID は " + Me.LoginControl.ID + vbNewLine + "パスワードは " + Me.LoginControl.Password + " です。")
End Sub
End Class
--------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ElementHost
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// ボタン押下時のイベントを定義します。
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("入力された ID は " + this.LoginControl.ID + "\n" + "パスワードは " + this.LoginControl.Password + " です。");
}
}
}
○ 動作確認
Visual Studio では「F5 キー」もしくは「メニュー>プロジェクト>デバッグ開始」でテストが可能なので動作させてみましょう。
【ElementHost サンプル動作イメージ】

【ElementHost サンプル動作イメージ ボタン押下時のメッセージボックス】

起動時には WPF ユーザコントロールの Storyboard が実行されますので、楕円がブラックからグラデーション表示に変化し、ボタン押下時にテキストボックスの内容が取得できれば WPF ユーザコントロールが正しく Windows フォームに配置できていることが確認できます。
■ まとめ
今回は「Windows フォームから WPF を利用する」方法について説明しました。この方法を用いれば部分的に WPF を試すこともできますので、うまく利用すれば既存の Windows フォームアプリケーションでも手軽にユーザエクスペリエンスを高めることができます。次回は「WPF に Windows フォームコントロールを組み込む」方法をご説明します。どうぞご期待下さい。