このチュートリアルでは、PropertyMap プロパティを使用して、ホストされている Windows フォーム コントロールの対応するプロパティに WPF プロパティをマップする方法について説明します。
このチュートリアルで説明するタスクは次のとおりです。
プロジェクトの作成。
アプリケーション レイアウトの定義。
新しいプロパティ マッピングの定義。
既定のプロパティ マッピングの削除。
既定のプロパティ マッピングを置き換えます。
既定のプロパティ マッピングの拡張。
完了すると、ホストされている Windows フォーム コントロールの対応するプロパティに WPF プロパティをマップできます。
[前提条件]
このチュートリアルを完了するには、次のコンポーネントが必要です。
- Visual Studio 2017
プロジェクトを作成して設定する
という名前の
PropertyMappingWithWfhSample
プロジェクトを作成します。ソリューション エクスプローラーで、WindowsFormsIntegration.dllという名前の WindowsFormsIntegration アセンブリへの参照を追加します。
ソリューション エクスプローラーで、System.Drawing アセンブリと System.Windows.Forms アセンブリへの参照を追加します。
アプリケーション レイアウトの定義
WPF ベースのアプリケーションでは、WindowsFormsHost 要素を使用して Windows フォーム コントロールをホストします。
アプリケーション レイアウトを定義するには
WPF デザイナーで Window1.xaml を開きます。
既存のコードを次のコードに置き換えます。
<Window x:Class="PropertyMappingWithWfh.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="PropertyMappingWithWfh" Height="300" Width="300" Loaded="WindowLoaded"> <DockPanel Name="panel1" LastChildFill="True"> <WindowsFormsHost Name="wfHost" DockPanel.Dock="Left" SizeChanged="Window1_SizeChanged" FontSize="20" /> </DockPanel> </Window>
コード エディターでWindow1.xaml.csを開きます。
ファイルの先頭に、次の名前空間をインポートします。
using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; using System.Windows.Forms.Integration;
Imports System.Drawing Imports System.Drawing.Drawing2D Imports System.Windows.Forms Imports System.Windows.Forms.Integration
新しいプロパティ マッピングの定義
WindowsFormsHost 要素には、いくつかの既定のプロパティ マッピングが用意されています。 新しいプロパティ マッピングを追加する場合は、Add 要素の WindowsFormsHostで PropertyMap メソッドを呼び出します。
新しいプロパティ マッピングを定義するには
Window1
クラスの定義に次のコードをコピーします。// The AddClipMapping method adds a custom // mapping for the Clip property. private void AddClipMapping() { wfHost.PropertyMap.Add( "Clip", new PropertyTranslator(OnClipChange)); } // The OnClipChange method assigns an elliptical clipping // region to the hosted control's Region property. private void OnClipChange(object h, String propertyName, object value) { WindowsFormsHost host = h as WindowsFormsHost; System.Windows.Forms.CheckBox cb = host.Child as System.Windows.Forms.CheckBox; if (cb != null) { cb.Region = this.CreateClipRegion(); } } // The Window1_SizeChanged method handles the window's // SizeChanged event. It calls the OnClipChange method explicitly // to assign a new clipping region to the hosted control. private void Window1_SizeChanged(object sender, SizeChangedEventArgs e) { this.OnClipChange(wfHost, "Clip", null); } // The CreateClipRegion method creates a Region from an // elliptical GraphicsPath. private Region CreateClipRegion() { GraphicsPath path = new GraphicsPath(); path.StartFigure(); path.AddEllipse(new System.Drawing.Rectangle( 0, 0, (int)wfHost.ActualWidth, (int)wfHost.ActualHeight ) ); path.CloseFigure(); return( new Region(path) ); }
' The AddClipMapping method adds a custom mapping ' for the Clip property. Private Sub AddClipMapping() wfHost.PropertyMap.Add( _ "Clip", _ New PropertyTranslator(AddressOf OnClipChange)) End Sub ' The OnClipChange method assigns an elliptical clipping ' region to the hosted control's Region property. Private Sub OnClipChange( _ ByVal h As Object, _ ByVal propertyName As String, _ ByVal value As Object) Dim host As WindowsFormsHost = h Dim cb As System.Windows.Forms.CheckBox = host.Child If cb IsNot Nothing Then cb.Region = Me.CreateClipRegion() End If End Sub ' The Window1_SizeChanged method handles the window's ' SizeChanged event. It calls the OnClipChange method explicitly ' to assign a new clipping region to the hosted control. Private Sub Window1_SizeChanged( _ ByVal sender As Object, _ ByVal e As SizeChangedEventArgs) Me.OnClipChange(wfHost, "Clip", Nothing) End Sub ' The CreateClipRegion method creates a Region from an ' elliptical GraphicsPath. Private Function CreateClipRegion() As [Region] Dim path As New GraphicsPath() path.StartFigure() path.AddEllipse(New System.Drawing.Rectangle( _ 0, _ 0, _ wfHost.ActualWidth, _ wfHost.ActualHeight)) path.CloseFigure() Return New [Region](path) End Function
AddClipMapping
メソッドは、Clip プロパティの新しいマッピングを追加します。OnClipChange
メソッドは、Clip プロパティを Windows フォームRegion プロパティに変換します。Window1_SizeChanged
メソッドは、ウィンドウの SizeChanged イベントを処理し、アプリケーション ウィンドウに合わせてクリッピング領域のサイズを設定します。
既定のプロパティ マッピングの削除
Remove 要素の WindowsFormsHostで PropertyMap メソッドを呼び出して、既定のプロパティ マッピングを削除します。
既定のプロパティ マッピングを削除するには
Window1
クラスの定義に次のコードをコピーします。// The RemoveCursorMapping method deletes the default // mapping for the Cursor property. private void RemoveCursorMapping() { wfHost.PropertyMap.Remove("Cursor"); }
' The RemoveCursorMapping method deletes the default ' mapping for the Cursor property. Private Sub RemoveCursorMapping() wfHost.PropertyMap.Remove("Cursor") End Sub
RemoveCursorMapping
メソッドは、Cursor プロパティの既定のマッピングを削除します。
既定のプロパティ マッピングの置き換え
既定のプロパティ マッピングを置き換えるには、既定のマッピングを削除し、Add 要素の WindowsFormsHostで PropertyMap メソッドを呼び出します。
既定のプロパティ マッピングを置き換えるには
Window1
クラスの定義に次のコードをコピーします。// The ReplaceFlowDirectionMapping method replaces the // default mapping for the FlowDirection property. private void ReplaceFlowDirectionMapping() { wfHost.PropertyMap.Remove("FlowDirection"); wfHost.PropertyMap.Add( "FlowDirection", new PropertyTranslator(OnFlowDirectionChange)); } // The OnFlowDirectionChange method translates a // Windows Presentation Foundation FlowDirection value // to a Windows Forms RightToLeft value and assigns // the result to the hosted control's RightToLeft property. private void OnFlowDirectionChange(object h, String propertyName, object value) { WindowsFormsHost host = h as WindowsFormsHost; System.Windows.FlowDirection fd = (System.Windows.FlowDirection)value; System.Windows.Forms.CheckBox cb = host.Child as System.Windows.Forms.CheckBox; cb.RightToLeft = (fd == System.Windows.FlowDirection.RightToLeft ) ? RightToLeft.Yes : RightToLeft.No; } // The cb_CheckedChanged method handles the hosted control's // CheckedChanged event. If the Checked property is true, // the flow direction is set to RightToLeft, otherwise it is // set to LeftToRight. private void cb_CheckedChanged(object sender, EventArgs e) { System.Windows.Forms.CheckBox cb = sender as System.Windows.Forms.CheckBox; wfHost.FlowDirection = ( cb.CheckState == CheckState.Checked ) ? System.Windows.FlowDirection.RightToLeft : System.Windows.FlowDirection.LeftToRight; }
' The ReplaceFlowDirectionMapping method replaces the ' default mapping for the FlowDirection property. Private Sub ReplaceFlowDirectionMapping() wfHost.PropertyMap.Remove("FlowDirection") wfHost.PropertyMap.Add( _ "FlowDirection", _ New PropertyTranslator(AddressOf OnFlowDirectionChange)) End Sub ' The OnFlowDirectionChange method translates a ' Windows Presentation Foundation FlowDirection value ' to a Windows Forms RightToLeft value and assigns ' the result to the hosted control's RightToLeft property. Private Sub OnFlowDirectionChange( _ ByVal h As Object, _ ByVal propertyName As String, _ ByVal value As Object) Dim host As WindowsFormsHost = h Dim fd As System.Windows.FlowDirection = _ CType(value, System.Windows.FlowDirection) Dim cb As System.Windows.Forms.CheckBox = host.Child cb.RightToLeft = IIf(fd = System.Windows.FlowDirection.RightToLeft, _ RightToLeft.Yes, _ RightToLeft.No) End Sub ' The cb_CheckedChanged method handles the hosted control's ' CheckedChanged event. If the Checked property is true, ' the flow direction is set to RightToLeft, otherwise it is ' set to LeftToRight. Private Sub cb_CheckedChanged( _ ByVal sender As Object, _ ByVal e As EventArgs) Dim cb As System.Windows.Forms.CheckBox = sender wfHost.FlowDirection = IIf(cb.CheckState = CheckState.Checked, _ System.Windows.FlowDirection.RightToLeft, _ System.Windows.FlowDirection.LeftToRight) End Sub
ReplaceFlowDirectionMapping
メソッドは、FlowDirection プロパティの既定のマッピングを置き換えます。OnFlowDirectionChange
メソッドは、FlowDirection プロパティを Windows フォームRightToLeft プロパティに変換します。cb_CheckedChanged
メソッドは、CheckedChanged コントロールの CheckBox イベントを処理します。 FlowDirection プロパティの値に基づいて、CheckState プロパティを割り当てます。
既定のプロパティ マッピングの拡張
既定のプロパティ マッピングを使用し、独自のマッピングで拡張することもできます。
既定のプロパティ マッピングを拡張するには
Window1
クラスの定義に次のコードをコピーします。// The ExtendBackgroundMapping method adds a property // translator if a mapping already exists. private void ExtendBackgroundMapping() { if (wfHost.PropertyMap["Background"] != null) { wfHost.PropertyMap["Background"] += new PropertyTranslator(OnBackgroundChange); } } // The OnBackgroundChange method assigns a specific image // to the hosted control's BackgroundImage property. private void OnBackgroundChange(object h, String propertyName, object value) { WindowsFormsHost host = h as WindowsFormsHost; System.Windows.Forms.CheckBox cb = host.Child as System.Windows.Forms.CheckBox; ImageBrush b = value as ImageBrush; if (b != null) { cb.BackgroundImage = new System.Drawing.Bitmap(@"C:\WINDOWS\Santa Fe Stucco.bmp"); } }
' The ExtendBackgroundMapping method adds a property ' translator if a mapping already exists. Private Sub ExtendBackgroundMapping() If wfHost.PropertyMap("Background") IsNot Nothing Then wfHost.PropertyMap("Background") = PropertyTranslator.Combine( _ wfHost.PropertyMap("Background"), _ PropertyTranslator.CreateDelegate( _ GetType(PropertyTranslator), _ Me, _ "OnBackgroundChange")) End If End Sub ' The OnBackgroundChange method assigns a specific image ' to the hosted control's BackgroundImage property. Private Sub OnBackgroundChange(ByVal h As Object, ByVal propertyName As String, ByVal value As Object) Dim host As WindowsFormsHost = h Dim cb As System.Windows.Forms.CheckBox = host.Child Dim b As ImageBrush = value If Not (b Is Nothing) Then cb.BackgroundImage = New System.Drawing.Bitmap("C:\WINDOWS\Santa Fe Stucco.bmp") End If End Sub
ExtendBackgroundMapping
メソッドは、既存の Background プロパティ マッピングにカスタム プロパティ トランスレーターを追加します。OnBackgroundChange
メソッドは、ホストされているコントロールの BackgroundImage プロパティに特定のイメージを割り当てます。OnBackgroundChange
メソッドは、既定のプロパティ マッピングが適用された後に呼び出されます。
プロパティ マッピングの初期化
Loaded イベント ハンドラーで前述のメソッドを呼び出して、プロパティ マッピングを設定します。
プロパティ マッピングを初期化するには
Window1
クラスの定義に次のコードをコピーします。// The WindowLoaded method handles the Loaded event. // It enables Windows Forms visual styles, creates // a Windows Forms checkbox control, and assigns the // control as the child of the WindowsFormsHost element. // This method also modifies property mappings on the // WindowsFormsHost element. private void WindowLoaded(object sender, RoutedEventArgs e) { System.Windows.Forms.Application.EnableVisualStyles(); // Create a Windows Forms checkbox control and assign // it as the WindowsFormsHost element's child. System.Windows.Forms.CheckBox cb = new System.Windows.Forms.CheckBox(); cb.Text = "Windows Forms checkbox"; cb.Dock = DockStyle.Fill; cb.TextAlign = ContentAlignment.MiddleCenter; cb.CheckedChanged += new EventHandler(cb_CheckedChanged); wfHost.Child = cb; // Replace the default mapping for the FlowDirection property. this.ReplaceFlowDirectionMapping(); // Remove the mapping for the Cursor property. this.RemoveCursorMapping(); // Add the mapping for the Clip property. this.AddClipMapping(); // Add another mapping for the Background property. this.ExtendBackgroundMapping(); // Cause the OnFlowDirectionChange delegate to be called. wfHost.FlowDirection = System.Windows.FlowDirection.LeftToRight; // Cause the OnClipChange delegate to be called. wfHost.Clip = new RectangleGeometry(); // Cause the OnBackgroundChange delegate to be called. wfHost.Background = new ImageBrush(); }
' The WindowLoaded method handles the Loaded event. ' It enables Windows Forms visual styles, creates ' a Windows Forms checkbox control, and assigns the ' control as the child of the WindowsFormsHost element. ' This method also modifies property mappings on the ' WindowsFormsHost element. Private Sub WindowLoaded( _ ByVal sender As Object, _ ByVal e As RoutedEventArgs) System.Windows.Forms.Application.EnableVisualStyles() ' Create a Windows Forms checkbox control and assign ' it as the WindowsFormsHost element's child. Dim cb As New System.Windows.Forms.CheckBox() cb.Text = "Windows Forms checkbox" cb.Dock = DockStyle.Fill cb.TextAlign = ContentAlignment.MiddleCenter AddHandler cb.CheckedChanged, AddressOf cb_CheckedChanged wfHost.Child = cb ' Replace the default mapping for the FlowDirection property. Me.ReplaceFlowDirectionMapping() ' Remove the mapping for the Cursor property. Me.RemoveCursorMapping() ' Add the mapping for the Clip property. Me.AddClipMapping() ' Add another mapping for the Background property. Me.ExtendBackgroundMapping() ' Cause the OnFlowDirectionChange delegate to be called. wfHost.FlowDirection = System.Windows.FlowDirection.LeftToRight ' Cause the OnClipChange delegate to be called. wfHost.Clip = New RectangleGeometry() ' Cause the OnBackgroundChange delegate to be called. wfHost.Background = New ImageBrush() End Sub
WindowLoaded
メソッドは、Loaded イベントを処理し、次の初期化を実行します。Windows フォームの CheckBox コントロールを作成します。
チュートリアルで前に定義したメソッドを呼び出して、プロパティ マッピングを設定します。
マップされたプロパティに初期値を割り当てます。
F5
押して、アプリケーションをビルドして実行します。 チェック ボックスをオンにすると、FlowDirection マッピングの効果が表示されます。 チェック ボックスをクリックすると、レイアウトの左右の向きが反転します。
こちらも参照ください
.NET Desktop feedback