Procedura dettagliata: mapping di proprietà tramite l'elemento WindowsFormsHost

Questa procedura dettagliata illustra come usare la proprietà per eseguire il PropertyMap mapping delle proprietà WPF alle proprietà corrispondenti in un controllo Windows Form ospitato.

Le attività illustrate nella procedura dettagliata sono le seguenti:

  • Creazione del progetto.

  • Definizione del layout dell'applicazione.

  • Definizione di un nuovo mapping delle proprietà.

  • Definizione di un mapping delle proprietà predefinito.

  • Sostituzione di un mapping delle proprietà predefinito.

  • Estensione di un mapping delle proprietà predefinito.

Al termine, sarà possibile eseguire il mapping delle proprietà WPF alle proprietà corrispondenti in un controllo Windows Form ospitato.

Prerequisiti

Per completare questa procedura dettagliata, è necessario disporre dei componenti seguenti:

  • Visual Studio 2017

Creare e configurare il progetto

  1. Creare un progetto app WPF denominato PropertyMappingWithWfhSample.

  2. In Esplora soluzioni aggiungere un riferimento all'assembly WindowsFormsIntegration, denominato WindowsFormsIntegration.dll.

  3. In Esplora soluzioni aggiungere riferimenti agli assembly System.Drawing e System.Windows.Forms.

Definizione del layout dell'applicazione

L'applicazione basata su WPF usa l'elemento WindowsFormsHost per ospitare un controllo Windows Form.

Per definire il layout dell'applicazione

  1. Aprire Window1.xaml nella finestra di progettazione WPF.

  2. Sostituire il codice esistente con quello seguente.

    <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>
    
  3. Aprire Window1.xaml.cs nell'editor di codice.

  4. Nella parte superiore del file importare gli spazi dei nomi seguenti.

    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
    

Definizione di un nuovo mapping delle proprietà

L'elemento WindowsFormsHost fornisce diversi mapping di proprietà predefiniti. Per aggiungere un nuovo mapping di proprietà, chiamare il Add metodo sull'elemento WindowsFormsHostPropertyMap.

Per definire un nuovo mapping delle proprietà

  • Copiare il codice seguente nella definizione della Window1 classe .

    // 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
    

    Il AddClipMapping metodo aggiunge un nuovo mapping per la Clip proprietà .

    Il OnClipChange metodo converte la Clip proprietà nella proprietà Windows FormRegion.

    Il Window1_SizeChanged metodo gestisce l'evento della SizeChanged finestra e ridimensiona l'area di ritaglio per adattarla alla finestra dell'applicazione.

Rimozione di un mapping delle proprietà predefinito

Rimuovere un mapping di proprietà predefinito chiamando il Remove metodo sull'elemento WindowsFormsHostPropertyMap.

Per rimuovere un mapping delle proprietà predefinito

  • Copiare il codice seguente nella definizione della Window1 classe .

    // 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
    

    Il RemoveCursorMapping metodo elimina il mapping predefinito per la Cursor proprietà .

Sostituzione di un mapping delle proprietà predefinito

Sostituire un mapping di proprietà predefinito rimuovendo il mapping predefinito e chiamando il Add metodo sull'elemento WindowsFormsHost .PropertyMap

Per sostituire un mapping delle proprietà predefinito

  • Copiare il codice seguente nella definizione della Window1 classe .

    // 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
    

    Il ReplaceFlowDirectionMapping metodo sostituisce il mapping predefinito per la FlowDirection proprietà .

    Il OnFlowDirectionChange metodo converte la FlowDirection proprietà nella proprietà Windows FormRightToLeft.

    Il cb_CheckedChanged metodo gestisce l'evento CheckedChanged nel CheckBox controllo . Assegna la FlowDirection proprietà in base al valore della CheckState proprietà

Estensione di un mapping delle proprietà predefinito

È possibile usare un mapping delle proprietà predefinito ed estenderlo con un mapping personalizzato.

Per estendere un mapping delle proprietà predefinito

  • Copiare il codice seguente nella definizione della Window1 classe .

    // 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
    

    Il ExtendBackgroundMapping metodo aggiunge un traduttore di proprietà personalizzato al mapping delle proprietà esistente Background .

    Il OnBackgroundChange metodo assegna un'immagine specifica alla proprietà del BackgroundImage controllo ospitato. Il OnBackgroundChange metodo viene chiamato dopo l'applicazione del mapping delle proprietà predefinito.

Inizializzazione dei mapping delle proprietà

Configurare i mapping delle proprietà chiamando i metodi descritti in precedenza nel Loaded gestore eventi.

Per inizializzare i mapping delle proprietà

  1. Copiare il codice seguente nella definizione della Window1 classe .

    // 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
    

    Il WindowLoaded metodo gestisce l'evento ed esegue l'inizializzazione Loaded seguente.

    • Crea un controllo Windows FormCheckBox.

    • Chiama i metodi definiti in precedenza nella procedura dettagliata per impostare i mapping delle proprietà.

    • Assegna i valori iniziali alle proprietà mappate.

  2. Premere F5 per compilare ed eseguire l'applicazione. Fare clic sulla casella di controllo per visualizzare l'effetto del FlowDirection mapping. Quando si seleziona la casella di controllo, il layout inverte l'orientamento da sinistra a destra.

Vedi anche