Tutorial: Asignar propiedades mediante el uso del elemento WindowsFormsHost

En este tutorial se muestra cómo utilizar la propiedad PropertyMap para asignar propiedades de WPF a sus propiedades correspondientes en un control de Windows Forms hospedado.

Las tareas ilustradas en este tutorial incluyen:

  • Crear el proyecto.

  • Definir el diseño de la aplicación.

  • Definir una nueva asignación de propiedad.

  • Quitar una asignación de propiedad predeterminada.

  • Reemplazar una asignación de propiedad predeterminada.

  • Extender una asignación de propiedad predeterminada.

Para ver una lista de código completa de las tareas ilustradas en este tutorial, vea Mapping Properties Using the WindowsFormsHost Element Sample.

Cuando haya terminado, podrá asignar propiedades de WPF a sus propiedades correspondientes de un control de Windows Forms hospedado.

Requisitos previos

Necesita los componentes siguientes para completar este tutorial:

  • Visual Studio 2008.

Crear el proyecto

Para crear y configurar el proyecto

  1. Cree un proyecto de aplicación de WPF denominado PropertyMappingWithWfh.

  2. En el Explorador de soluciones, agregue una referencia al ensamblado WindowsFormsIntegration, denominado WindowsFormsIntegration.dll.

  3. En el Explorador de soluciones, agregue referencias a los ensamblados System.Drawing y System.Windows.Forms .

Definir el diseño de la aplicación

La aplicación basada en WPF utiliza el elemento WindowsFormsHost para hospedar un control de Windows Forms.

Para definir el diseño de la aplicación

  1. Abra Window1.xaml en WPF Designer.

  2. Reemplace el código existente con el siguiente código.

    <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>
    
    <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>
    
  3. Abra Window1.xaml.cs en el Editor de código.

  4. En la parte superior del archivo, importe los espacios de nombres siguientes.

    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;
    

Definir una nueva asignación de propiedad

El elemento WindowsFormsHost proporciona varias asignaciones de propiedad predeterminadas. Para agregar una nueva asignación de propiedad, se llama al método Add de la propiedad PropertyMap del elemento WindowsFormsHost.

Para definir una nueva asignación de propiedad

  • Copie el código siguiente en la definición de la clase 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) );
    }
    

    El método AddClipMapping agrega una nueva asignación para la propiedad Clip.

    El método OnClipChange convierte la propiedad Clip en la propiedad Region de Windows Forms

    El método Window1_SizeChanged controla el evento SizeChanged de la ventana y cambia el tamaño de la zona de recorte para ajustarlo a la ventana de la aplicación.

Quitar una asignación de propiedad predeterminada

Para quitar una asignación de propiedad predeterminada, llame al método Remove de la propiedad PropertyMap del elemento WindowsFormsHost.

Para quitar una asignación de propiedad predeterminada

  • Copie el código siguiente en la definición de la clase 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");
    }
    

    El método RemoveCursorMapping elimina la asignación predeterminada para la propiedad Cursor.

Reemplazar una asignación de propiedad predeterminada

Para reemplazar una asignación de propiedad predeterminada, quite la asignación predeterminada y llame al método Add de la propiedad PropertyMap del elemento WindowsFormsHost.

Para reemplazar una asignación de propiedad predeterminada

  • Copie el código siguiente en la definición de la clase 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;
    }
    

    El método ReplaceFlowDirectionMapping reemplaza la asignación predeterminada para la propiedad FlowDirection.

    El método OnFlowDirectionChange convierte la propiedad FlowDirection en la propiedad RightToLeft de Windows Forms

    El método cb_CheckedChanged controla el evento CheckedChanged del control CheckBox. Asigna la propiedad FlowDirection basándose en el valor de la propiedad CheckState

Extender una asignación de propiedad predeterminada

Puede utilizar una asignación de propiedad predeterminada y también extenderla con su propia asignación.

Para extender una asignación de propiedad predeterminada

  • Copie el código siguiente en la definición de la clase 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");
        }
    }
    

    El método ExtendBackgroundMapping agrega un convertidor de propiedades personalizado a la asignación existente de la propiedad Background.

    El método OnBackgroundChange asigna una imagen concreta a la propiedad BackgroundImage de control hospedado. Se llama al método OnBackgroundChange una vez aplicada la asignación de propiedad predeterminada.

Inicializar las asignaciones de propiedad

Configure las asignaciones de propiedad llamando a los métodos previamente descritos del controlador de eventos Loaded.

Para inicializar las asignaciones de propiedad

  1. Copie el código siguiente en la definición de la clase 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();
    }
    

    El método WindowLoaded controla el evento Loaded y realiza la inicialización siguiente.

    • Crea un control CheckBox de Windows Forms.

    • Llama a los métodos que definió anteriormente en el tutorial para configurar las asignaciones de propiedad.

    • Asigna los valores iniciales a las propiedades asignadas.

  2. Presione F5 para compilar y ejecutar la aplicación. Haga clic en la casilla para ver el efecto de la asignación de FlowDirection. Al hacer clic en la casilla, el diseño invierte su orientación de izquierda a derecha.

Vea también

Tareas

Tutorial: Hospedar un control de Windows Forms en WPF

Referencia

WindowsFormsHost.PropertyMap

ElementHost.PropertyMap

WindowsFormsHost

Conceptos

Asignación de propiedades en formularios Windows Forms y WPF

Otros recursos

WPF Designer