Demonstra Passo a passo: Mapeando propriedades usando o elemento WindowsFormsHost
Este passo a passo mostra como usar a propriedade PropertyMap para mapear propriedades WPF às propriedades correspondentes em um controle Windows Forms hospedado.
Tarefas ilustradas nesta explicação passo a passo incluem:
Criando o projeto
Definindo o layout do aplicativo.
Definindo um novo mapeamento de propriedade.
Removendo um mapeamento de propriedade padrão.
Substituindo um mapeamento padrão de propriedades.
Estendendo um mapeamento de propriedade padrão.
For a complete code listing of the tasks illustrated in this walkthrough, see Mapeamento de propriedades usando o exemplo de elemento WindowsFormsHost.
Quando você terminar, você será capaz de mapear propriedades de WPF às propriedades correspondentes em um controle Windows Forms hospedado.
Observação As caixas de diálogo e comandos de menu você vê podem diferir daqueles descritos na ajuda dependendo de suas configurações ativas ou versão. Para alterar as configurações, escolher Importar e exportar configurações on the Ferramentas menu. Para obter mais informações, consulte Configurações do Visual Studio.
Pré-requisitos
Para completar este passo a passo, são necessários os seguintes componentes:
- Visual Studio 2008.
Criando o projeto
Para criar e configurar o projeto
Crie um projeto de Aplicativo WPF chamado PropertyMappingWithWfh.
No Solution Explorer, acrescente uma referência ao assembly WindowsFormsIntegration, que é chamado WindowsFormsIntegration.dll.
No Solution Explorer, adicione referências aos assemblies System.Drawing e System.Windows.Forms.
Definindo o layout do aplicativo
O aplicativo basead em WPF usa o elemento WindowsFormsHost para hospedar um controle Windows Forms.
Para definir o layout do aplicativo
Abra Window1.xaml no WPF Designer.
Substitua o código existente com o seguinte código.
<Window x:Class="Window1" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://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>
<Window x:Class="PropertyMappingWithWfh.Window1" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://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>
No Editor de Código, abra Window1.xaml.cs.
Na parte superior do arquivo, importe os seguintes namespaces.
Imports System.Drawing Imports System.Drawing.Drawing2D Imports System.Windows.Forms Imports System.Windows.Forms.Integration
using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; using System.Windows.Forms.Integration;
Definindo um novo mapeamento de propriedade.
O elemento WindowsFormsHost fornece vários mapeamentos padrão de propriedades. Você adiciona um novo mapeamento de propriedade chamando o método Add no PropertyMap do elemento WindowsFormsHost.
Para definir novos mapeamentos de propriedades
Copie o seguinte código na definição da classe de Window1.
' 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
// 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) ); }
O método AddClipMapping adiciona um novo mapeamento para a propriedade Clip.
O método OnClipChange traduz a propriedade Clip para a propriedade Region do Windows Forms.
O método Window1_SizeChanged trata o evento SizeChanged da janela e dimensiona a região de corte para que este se encaixe na janela do aplicativo.
Removendo um Mapeamento de Propriedade Padrão.
Remova um mapeamento de propriedade padrão chamando o método Remove no PropertyMap do elemento WindowsFormsHost.
Remover um mapeamento de propriedade padrão.
Copie o seguinte código na definição da classe de Window1.
' The RemoveCursorMapping method deletes the default ' mapping for the Cursor property. Private Sub RemoveCursorMapping() wfHost.PropertyMap.Remove("Cursor") End Sub
// The RemoveCursorMapping method deletes the default // mapping for the Cursor property. private void RemoveCursorMapping() { wfHost.PropertyMap.Remove("Cursor"); }
O método RemoveCursorMapping deleta o mapeamento padrão para a propriedade Cursor.
Substituindo um mapeamento padrão de propriedades
Substitua o mapeamento padrão de propriedades removendo o mapeamento padrão e chamando o método Add no PropertyMap do elemento WindowsFormsHost.
Para substituir um mapeamento padrão de propriedades
Copie o seguinte código na definição da classe de Window1.
' 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
// 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; }
O método ReplaceFlowDirectionMapping substitui o mapeamento padrão para a propriedade FlowDirection.
O método OnFlowDirectionChange traduz a propriedade FlowDirection para a propriedade RightToLeft do Windows Forms.
O método cb_CheckedChanged trata o evento CheckedChanged no controle CheckBox. Ele atribui a propriedade FlowDirection com base no valor da propriedade CheckState
Estendendo um Mapeamento de Propriedade Padrão.
Você pode usar um mapeamento de propriedade padrão e também estendê-lo com seu próprio mapeamento.
Para estender um mapeamento de propriedade padrão
Copie o seguinte código na definição da classe de Window1.
' 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
// 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"); } }
O método ExtendBackgroundMapping adiciona um tradutor de propriedade personalizado para o mapeamento existente da propriedade Background.
O método OnBackgroundChange define uma imagem específica para a propriedade BackgroundImage do controle hospedado. O método OnBackgroundChange é chamado depois que o mapeamento de propriedade padrão é aplicado.
Inicializando Seus Mapeamentos de Propriedades
Configure seus mapeamentos de propriedades chamando os métodos descritos anteriormente no tratador do evento Loaded.
Para inicializar seus mapeamentos de propriedades
Copie o seguinte código na definição da classe de 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 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
// 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(); }
O método WindowLoaded manipula o evento Loaded e realiza a seguinte inicialização.
Cria um controle Windows Forms CheckBox.
Chame os métodos que você definiu previamente neste passo a passo para definir os mapeamentos de propriedades.
Defina seus valores iniciais para as propriedades mapeadas.
Pressione F5 para criar e executar o aplicativo. Clique na caixa de seleção para ver o efeito do mapeamento de FlowDirection. Quando você clica na caixa de seleção, o layout inverte sua orientação esquerda-direita.
Consulte também
Tarefas
Conceitos
Formulários do Windows e mapeamento de propriedades do WPF