逐步解說:使用 WindowsFormsHost 項目對應屬性
本操作指引將向您展示如何使用 PropertyMap 屬性,將 WPF 屬性對應到裝載的 Windows Forms 控制項上的相應屬性。
這個逐步解說中所述的工作包括:
建立專案。
定義應用程式版面配置。
定義新的屬性對應。
移除預設屬性對應。
取代預設屬性對應。
擴充預設屬性對應。
完成時,您可以將 WPF 屬性對應到到裝載的 Windows Forms 控制項上的相應屬性。
必要條件
您需要下列元件才能完成這個逐步解說:
- Visual Studio 2017
建立並設定專案
建立名稱為
PropertyMappingWithWfhSample
的 WPF 應用程式專案。在 [方案總管] 中,新增名為 WindowsFormsIntegration.dll 之 WindowsFormsIntegration 組件的參考。
在 [方案總管] 中,新增 System.Drawing 和 System.Windows.Forms 組件的參考。
定義應用程式版面配置
WPF 型應用程式會使用 WindowsFormsHost 項目來託管 Windows Forms 控制項。
定義應用程式版面配置
在 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 項目提供了一些預設的屬性對應。 您可以透過在WindowsFormsHost項目的屬性PropertyMap上呼叫 Add 方法,以新增一個新的屬性對應。
定義新的屬性對應
將下列程式碼複製到
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 Forms Region 的屬性。Window1_SizeChanged
方法會處理視窗的 SizeChanged 事件,並調整成剪輯區域的大小以符合應用程式視窗。
移除預設屬性對應
您可以透過在 WindowsFormsHost項目的屬性PropertyMap 上呼叫 Remove 方法,以移除一個預設屬性對應。
移除預設屬性對應
將下列程式碼複製到
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 屬性的預設對應。
取代預設屬性對應
藉由移除預設對應,並在 WindowsFormsHost項目的屬性PropertyMap 上呼叫 Add 方法,以取代預設屬性對應。
移除預設屬性對應
將下列程式碼複製到
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 Forms RightToLeft 的屬性。cb_CheckedChanged
方法會處理 CheckBox 控制項上的 CheckedChanged 事件。 將 CheckState 屬性的值指派給 FlowDirection 屬性
擴充預設屬性對應
您可以使用預設屬性對應,也可以使用自己的對應來進行擴充。
擴充預設屬性對應
將下列程式碼複製到
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 FormsCheckBox 控制項。
呼叫您稍早在本逐步解說中所定義的方法來設定屬性對應。
將初始值指派給對應的屬性。
按 F5 以建置並執行應用程式。 按一下核取方塊以查看 FlowDirection 對應的效果。 當您按一下核取方塊時,版面配置會反轉其左右方向。