Tutorial: Asignar propiedades mediante el uso del control ElementHost

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

Las tareas ilustradas en este tutorial incluyen:

  • Crear el proyecto.

  • Definir una nueva asignación de propiedad.

  • Quitar 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 ElementHost Control Sample.

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

Requisitos previos

Necesita los componentes siguientes para completar este tutorial:

  • Visual Studio 2008.

Crear el proyecto

Para crear el proyecto

  1. Cree un proyecto de aplicación de Windows Forms denominado PropertyMappingWithElementHost. Para obtener más información, vea Cómo: Crear un nuevo proyecto de aplicación de Windows Forms.

  2. En el Explorador de soluciones, agregue referencias a los ensamblados de WPF siguientes. 

    • PresentationCore

    • PresentationFramework

    • WindowsBase

    • WindowsFormsIntegration

  3. Copie el código siguiente en la parte superior del archivo de código Form1.

    Imports System.Windows
    Imports System.Windows.Media
    Imports System.Windows.Media.Imaging
    Imports System.Windows.Forms.Integration
    
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Forms.Integration;
    
  4. Abra Form1 en el Diseñador de Windows Forms. Haga doble clic en el formulario para agregar un controlador para el evento Load.

  5. Vuelva al Diseñador de Windows Forms y agregue un controlador para el evento Resize del formulario. Para obtener más información, consulte Cómo: Crear controladores de eventos con el diseñador.

  6. Declare un campo ElementHost en la clase Form1.

    Private elemHost As ElementHost = Nothing
    
    ElementHost elemHost = null;
    

Definir nuevas asignaciones de propiedad

El control ElementHost 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 control ElementHost.

Para definir las nuevas asignaciones de propiedad

  1. Copie el código siguiente en la definición de la clase Form1.

    ' The AddMarginMapping method adds a new property mapping
    ' for the Margin property.
    Private Sub AddMarginMapping()
    
        elemHost.PropertyMap.Add( _
            "Margin", _
            New PropertyTranslator(AddressOf OnMarginChange))
    
    End Sub
    
    
    ' The OnMarginChange method implements the mapping 
    ' from the Windows Forms Margin property to the
    ' Windows Presentation Foundation Margin property.
    '
    ' The provided Padding value is used to construct 
    ' a Thickness value for the hosted element's Margin
    ' property.
    Private Sub OnMarginChange( _
    ByVal h As Object, _
    ByVal propertyName As String, _
    ByVal value As Object)
    
        Dim host As ElementHost = h
        Dim p As Padding = CType(value, Padding)
        Dim wpfButton As System.Windows.Controls.Button = host.Child
    
    
        Dim t As New Thickness(p.Left, p.Top, p.Right, p.Bottom)
    
        wpfButton.Margin = t
    
    End Sub
    
    // The AddMarginMapping method adds a new property mapping
    // for the Margin property.
    private void AddMarginMapping()
    {
        elemHost.PropertyMap.Add(
            "Margin",
            new PropertyTranslator(OnMarginChange));
    }
    
    // The OnMarginChange method implements the mapping 
    // from the Windows Forms Margin property to the
    // Windows Presentation Foundation Margin property.
    //
    // The provided Padding value is used to construct 
    // a Thickness value for the hosted element's Margin
    // property.
    private void OnMarginChange(object h, String propertyName, object value)
    {
        ElementHost host = h as ElementHost;
        Padding p = (Padding)value;
        System.Windows.Controls.Button wpfButton = 
            host.Child as System.Windows.Controls.Button;
    
        Thickness t = new Thickness(p.Left, p.Top, p.Right, p.Bottom );
    
        wpfButton.Margin = t;
    }
    

    El método AddMarginMapping agrega una nueva asignación para la propiedad Margin.

    El método OnMarginChange convierte la propiedad Margin en la propiedad Margin de WPF

  2. Copie el código siguiente en la definición de la clase Form1.

    ' The AddRegionMapping method assigns a custom 
    ' mapping for the Region property.
    Private Sub AddRegionMapping()
    
        elemHost.PropertyMap.Add( _
            "Region", _
            New PropertyTranslator(AddressOf OnRegionChange))
    
    End Sub
    
    
    ' The OnRegionChange method assigns an EllipseGeometry to
    ' the hosted element's Clip property.
    Private Sub OnRegionChange( _
    ByVal h As Object, _
    ByVal propertyName As String, _
    ByVal value As Object)
    
        Dim host As ElementHost = h
    
        Dim wpfButton As System.Windows.Controls.Button = host.Child
    
        wpfButton.Clip = New EllipseGeometry(New Rect( _
            0, _
            0, _
            wpfButton.ActualWidth, _
            wpfButton.ActualHeight))
    
    End Sub
    
    
    ' The Form1_Resize method handles the form's Resize event.
    ' It calls the OnRegionChange method explicitly to 
    ' assign a new clipping geometry to the hosted element.
    Private Sub Form1_Resize( _
    ByVal sender As Object, _
    ByVal e As EventArgs) Handles MyBase.Resize
    
        If elemHost IsNot Nothing Then
            Me.OnRegionChange(elemHost, "Region", Nothing)
        End If
    
    End Sub
    
    // The AddRegionMapping method assigns a custom 
    // mapping for the Region property.
    private void AddRegionMapping()
    {
        elemHost.PropertyMap.Add(
            "Region",
            new PropertyTranslator(OnRegionChange));
    }
    
    // The OnRegionChange method assigns an EllipseGeometry to
    // the hosted element's Clip property.
    private void OnRegionChange(
        object h, 
        String propertyName, 
        object value)
    {
        ElementHost host = h as ElementHost;
        System.Windows.Controls.Button wpfButton = 
            host.Child as System.Windows.Controls.Button;
    
        wpfButton.Clip = new EllipseGeometry(new Rect(
            0, 
            0, 
            wpfButton.ActualWidth, 
            wpfButton.ActualHeight));
    }
    
    // The Form1_Resize method handles the form's Resize event.
    // It calls the OnRegionChange method explicitly to 
    // assign a new clipping geometry to the hosted element.
    private void Form1_Resize(object sender, EventArgs e)
    {
        this.OnRegionChange(elemHost, "Region", null);
    }
    

    El método AddRegionMapping agrega una nueva asignación para la propiedad Region.

    El método OnRegionChange convierte la propiedad Region en la propiedad Clip de WPF

    El método Form1_Resize controla el evento Resize del formulario y cambia el tamaño de la zona de recorte para ajustar el elemento hospedado.

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 control ElementHost.

Para quitar una asignación de propiedad predeterminada

  • Copie el código siguiente en la definición de la clase Form1.

    ' The RemoveCursorMapping method deletes the default
    ' mapping for the Cursor property.
    Private Sub RemoveCursorMapping()
        elemHost.PropertyMap.Remove("Cursor")
    End Sub
    
    // The RemoveCursorMapping method deletes the default
    // mapping for the Cursor property.
    private void RemoveCursorMapping()
    {
        elemHost.PropertyMap.Remove("Cursor");
    }
    

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

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 Form1.

    ' The ExtendBackColorMapping method adds a property
    ' translator if a mapping already exists.
    Private Sub ExtendBackColorMapping()
    
        If elemHost.PropertyMap("BackColor") IsNot Nothing Then
    
            elemHost.PropertyMap("BackColor") = PropertyTranslator.Combine( _
                elemHost.PropertyMap("BackColor"), _
                PropertyTranslator.CreateDelegate( _
                GetType(PropertyTranslator), _
                Me, _
                "OnBackColorChange"))
        End If
    
    End Sub
    
    
    ' The OnBackColorChange method assigns a specific image 
    ' to the hosted element's Background property.
    Private Sub OnBackColorChange( _
    ByVal h As Object, _
    ByVal propertyName As String, _
    ByVal value As Object)
    
        Dim host As ElementHost = h
        Dim wpfButton As System.Windows.Controls.Button = host.Child
        Dim b As New ImageBrush(New BitmapImage( _
            New Uri("file:///C:\WINDOWS\Santa Fe Stucco.bmp")))
        wpfButton.Background = b
    
    End Sub
    
    // The ExtendBackColorMapping method adds a property
    // translator if a mapping already exists.
    private void ExtendBackColorMapping()
    {
        if (elemHost.PropertyMap["BackColor"] != null)
        {
            elemHost.PropertyMap["BackColor"] += 
                new PropertyTranslator(OnBackColorChange);
        }
    }
    
    // The OnBackColorChange method assigns a specific image 
    // to the hosted element's Background property.
    private void OnBackColorChange(object h, String propertyName, object value)
    {
        ElementHost host = h as ElementHost;
        System.Windows.Controls.Button wpfButton = 
            host.Child as System.Windows.Controls.Button;
    
        ImageBrush b = new ImageBrush(new BitmapImage(
            new Uri(@"file:///C:\WINDOWS\Santa Fe Stucco.bmp")));
        wpfButton.Background = b;
    }
    

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

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

Inicializar las asignaciones de propiedad

Para inicializar las asignaciones de propiedad

  1. Copie el código siguiente en la definición de la clase Form1.

    Private Sub Form1_Load( _
    ByVal sender As Object, _
    ByVal e As EventArgs) Handles MyBase.Load
    
        ' Create the ElementHost control.
        elemHost = New ElementHost()
        elemHost.Dock = DockStyle.Fill
        Me.Controls.Add(elemHost)
    
        ' Create a Windows Presentation Foundation Button element 
        ' and assign it as the ElementHost control's child. 
        Dim wpfButton As New System.Windows.Controls.Button()
        wpfButton.Content = "Windows Presentation Foundation Button"
        elemHost.Child = wpfButton
    
        ' Map the Margin property.
        Me.AddMarginMapping()
    
        ' Remove the mapping for the Cursor property.
        Me.RemoveCursorMapping()
    
        ' Add a mapping for the Region property.
        Me.AddRegionMapping()
    
        ' Add another mapping for the BackColor property.
        Me.ExtendBackColorMapping()
    
        ' Cause the OnMarginChange delegate to be called.
        elemHost.Margin = New Padding(23, 23, 23, 23)
    
        ' Cause the OnRegionChange delegate to be called.
        elemHost.Region = New [Region]()
    
        ' Cause the OnBackColorChange delegate to be called.
        elemHost.BackColor = System.Drawing.Color.AliceBlue
    
    End Sub
    
    private void Form1_Load(object sender, EventArgs e)
    {
        // Create the ElementHost control.
        elemHost = new ElementHost();
        elemHost.Dock = DockStyle.Fill;
        this.Controls.Add(elemHost);
    
        // Create a Windows Presentation Foundation Button element 
        // and assign it as the ElementHost control's child. 
        System.Windows.Controls.Button wpfButton = new System.Windows.Controls.Button();
        wpfButton.Content = "Windows Presentation Foundation Button";
        elemHost.Child = wpfButton;
    
        // Map the Margin property.
        this.AddMarginMapping();
    
        // Remove the mapping for the Cursor property.
        this.RemoveCursorMapping();
    
        // Add a mapping for the Region property.
        this.AddRegionMapping();
    
        // Add another mapping for the BackColor property.
        this.ExtendBackColorMapping();
    
        // Cause the OnMarginChange delegate to be called.
        elemHost.Margin = new Padding(23, 23, 23, 23);
    
        // Cause the OnRegionChange delegate to be called.
        elemHost.Region = new Region();
    
        // Cause the OnBackColorChange delegate to be called.
        elemHost.BackColor = System.Drawing.Color.AliceBlue;
    }
    

    El método Form1_Load controla el evento Load y realiza la inicialización siguiente.

    • Crea un elemento Button de WPF.

    • 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.

Vea también

Referencia

ElementHost.PropertyMap

WindowsFormsHost.PropertyMap

WindowsFormsHost

Conceptos

Asignación de propiedades en formularios Windows Forms y WPF

Tutorial: Hospedar un control compuesto de WPF en formularios Windows Forms

Otros recursos

WPF Designer