Compartir a través de


Tutorial: Organizar controles de Formularios Windows Forms en WPF

En este tutorial se muestra cómo usar características de diseño de WPF para organizar controles de Windows Forms en una aplicación híbrida.

Las tareas que se muestran en este tutorial incluyen:

  • Creación del proyecto.
  • Usar la configuración de diseño predeterminada.
  • Ajuste de tamaño al contenido.
  • Uso del posicionamiento absoluto.
  • Especificar el tamaño explícitamente.
  • Establecer las propiedades de diseño.
  • Descripción de las limitaciones del orden z.
  • Acoplamiento.
  • Establecer visibilidad.
  • Hospedar un control que no se ajusta.
  • Escalada.
  • Rotante.
  • Establecer relleno y márgenes.
  • Uso de contenedores de diseño dinámico.

Para obtener una lista de código completa de las tareas que se muestran en este tutorial, vea Organizar controles de Formularios Windows Forms en el ejemplo de WPF.

Cuando haya terminado, comprenderá las características de diseño de Windows Forms en aplicaciones basadas en WPF.

Prerrequisitos

Necesita Visual Studio para completar este tutorial.

Creación del proyecto

Para crear y configurar el proyecto, siga estos pasos:

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

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

    • WindowsFormsIntegration
    • System.Windows.Forms
    • System.Drawing
  3. Haga doble clic en MainWindow.xaml para abrirlo en la vista XAML.

  4. En el elemento Window, agregue la siguiente asignación de espacio de nombres de Windows Forms.

    xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    
  5. En el Grid elemento, establezca la ShowGridLines propiedad true en y defina cinco filas y tres columnas.

    <Grid ShowGridLines="true">
      <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
      </Grid.RowDefinitions>
    
      <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
      </Grid.ColumnDefinitions>
    

Usar la configuración de diseño predeterminada

De forma predeterminada, el WindowsFormsHost elemento controla el diseño del control hospedado de Windows Forms.

Para usar la configuración de diseño predeterminada, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Default layout. -->
    <Canvas Grid.Row="0" Grid.Column="0">
      <WindowsFormsHost Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. Presione F5 para compilar y ejecutar la aplicación. El control de Windows Forms System.Windows.Forms.Button aparece en el Canvas. El control hospedado tiene un tamaño basado en su contenido y el WindowsFormsHost elemento tiene el tamaño para acomodar el control hospedado.

Dimensionamiento según el contenido

El WindowsFormsHost elemento garantiza que el control hospedado tenga el tamaño para mostrar su contenido correctamente.

Para ajustar el tamaño al contenido, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Sizing to content. -->
    <Canvas Grid.Row="1" Grid.Column="0">
      <WindowsFormsHost Background="Orange">
        <wf:Button Text="Windows Forms control with more content" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
    <Canvas Grid.Row="2" Grid.Column="0">
      <WindowsFormsHost FontSize="24" Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. Presione F5 para compilar y ejecutar la aplicación. Los dos nuevos botones de control están dimensionados para mostrar correctamente la cadena de texto más larga y el tamaño de fuente mayor, y los elementos WindowsFormsHost se redimensionan para acomodar los controles hospedados.

Uso del posicionamiento absoluto

Puede usar el posicionamiento absoluto para colocar el WindowsFormsHost elemento en cualquier parte de la interfaz de usuario (UI).

Para usar el posicionamiento absoluto, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Absolute positioning. -->
    <Canvas Grid.Row="3" Grid.Column="0">
      <WindowsFormsHost Canvas.Top="20" Canvas.Left="20" Background="Yellow">
        <wf:Button Text="Windows Forms control with absolute positioning" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. Presione F5 para compilar y ejecutar la aplicación. El WindowsFormsHost elemento se coloca 20 píxeles desde la parte superior de la celda de cuadrícula y 20 píxeles desde la izquierda.

Especificar el tamaño explícitamente

Puede especificar el tamaño del WindowsFormsHost elemento mediante las Width propiedades y Height .

Para especificar explícitamente el tamaño, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Explicit sizing. -->
    <Canvas Grid.Row="4" Grid.Column="0">
      <WindowsFormsHost Width="50" Height="70" Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. Presione F5 para compilar y ejecutar la aplicación. El WindowsFormsHost elemento se establece en un tamaño de 50 píxeles de ancho por 70 píxeles de alto, que es menor que la configuración de diseño predeterminada. El contenido del control de Windows Forms se reorganiza en consecuencia.

Establecer propiedades de diseño

Establezca siempre las propiedades relacionadas con el diseño en el control hospedado mediante las propiedades del WindowsFormsHost elemento . Establecer las propiedades de diseño directamente en el control hospedado producirá resultados no deseados.

Establecer propiedades relacionadas con el diseño en el control hospedado en XAML no tiene ningún efecto.

Para ver los efectos de establecer propiedades en el control hospedado, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Setting hosted control properties directly. -->
    <Canvas Grid.Row="0" Grid.Column="1">
      <WindowsFormsHost Width="160" Height="50" Background="Yellow">
        <wf:Button Name="button1" Click="button1_Click" Text="Click me" FlatStyle="Flat" BackColor="Green"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. En el Explorador de soluciones, haga doble clic en MainWindow.xaml.vb o MainWindow.xaml.cs para abrirlo en el Editor de código.

  3. Copie el código siguiente en la definición de clase MainWindow :

    private void button1_Click(object sender, EventArgs e )
    {
        System.Windows.Forms.Button b = sender as System.Windows.Forms.Button;
    
        b.Top = 20;
        b.Left = 20;
    }
    
    Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim b As System.Windows.Forms.Button = sender
    
        b.Top = 20
        b.Left = 20
    
    End Sub
    
  4. Presione F5 para compilar y ejecutar la aplicación.

  5. Haga clic en el botón Click me. El controlador de eventos button1_Click establece las propiedades Top y Left en el control hospedado. Esto hace que el control hospedado se cambie la posición dentro del WindowsFormsHost elemento . El host mantiene la misma área de pantalla, pero el control hospedado se recorta. En su lugar, el control hospedado siempre debe rellenar el WindowsFormsHost elemento.

Descripción de las limitaciones del orden Z

Los elementos visibles WindowsFormsHost siempre se dibujan encima de otros elementos de WPF y no se ven afectados por el orden z. Para ver este comportamiento de orden z, haga lo siguiente:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Z-order demonstration. -->
    <Canvas Grid.Row="1" Grid.Column="1">
      <WindowsFormsHost Canvas.Top="20" Canvas.Left="20" Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
      <Label Content="A WPF label" FontSize="24"/>
    </Canvas>
    
  2. Presione F5 para compilar y ejecutar la aplicación. El elemento WindowsFormsHost se pinta sobre el elemento etiqueta.

Acoplamiento

WindowsFormsHost el elemento admite la funcionalidad de acoplamiento de WPF. Establezca la Dock propiedad adjunta para acoplar el control alojado en un elemento DockPanel.

Para acoplar un control hospedado, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Docking a WindowsFormsHost element. -->
    <DockPanel LastChildFill="false"  Grid.Row="2" Grid.Column="1">
      <WindowsFormsHost DockPanel.Dock="Right"  Canvas.Top="20" Canvas.Left="20" Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </DockPanel>
    
  2. Presione F5 para compilar y ejecutar la aplicación. El WindowsFormsHost elemento está acoplado al lado derecho del DockPanel elemento.

Establecer visibilidad

Puede hacer que el control de Windows Forms sea invisible o contraerlo estableciendo la propiedad Visibility en el elemento WindowsFormsHost. Cuando un control es invisible, no se muestra, pero ocupa el espacio de diseño. Cuando se contrae un control, no se muestra ni tampoco ocupa espacio en el diseño.

Para establecer la visibilidad de un control hospedado, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Setting Visibility to hidden and collapsed. -->
    <StackPanel Grid.Row="3" Grid.Column="1">
      <Button Name="button2" Click="button2_Click" Content="Click to make invisible" Background="OrangeRed"/>
      <WindowsFormsHost Name="host1"  Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
      <Button Name="button3" Click="button3_Click" Content="Click to collapse" Background="OrangeRed"/>
    </StackPanel>
    
  2. En MainWindow.xaml.vb o MainWindow.xaml.cs, copie el código siguiente en la definición de clase:

    private void button2_Click(object sender, EventArgs e)
    {
        this.host1.Visibility = Visibility.Hidden;
    }
    
    private void button3_Click(object sender, EventArgs e)
    {
        this.host1.Visibility = Visibility.Collapsed;
    }
    
    Private Sub button2_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Me.host1.Visibility = Windows.Visibility.Hidden
    End Sub
    
    
    Private Sub button3_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Me.host1.Visibility = Windows.Visibility.Collapsed
    End Sub
    
  3. Presione F5 para compilar y ejecutar la aplicación.

  4. Haga clic en el botón Click para hacer invisible para hacer que el elemento WindowsFormsHost sea invisible.

  5. Haga clic en el botón Hacer clic para contraer para ocultar completamente el WindowsFormsHost elemento del diseño. Cuando se contrae el control de Windows Forms, los elementos circundantes se reorganizan para ocupar su espacio.

Alojar un control que no se adapta

Algunos controles de Windows Forms tienen un tamaño fijo y no se extienden para rellenar el espacio disponible en el diseño. Por ejemplo, el MonthCalendar control muestra un mes en un espacio fijo.

Para hospedar un control que no se ajusta, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Hosting a control that does not stretch. -->
    <!-- The MonthCalendar has a discrete size. -->
    <StackPanel Grid.Row="4" Grid.Column="1">
      <Label Content="A WPF element" Background="OrangeRed"/>
      <WindowsFormsHost Background="Yellow">
        <wf:MonthCalendar/>
      </WindowsFormsHost>
      <Label Content="Another WPF element" Background="OrangeRed"/>
    </StackPanel>
    
  2. Presione F5 para compilar y ejecutar la aplicación. El elemento WindowsFormsHost está centrado en la fila de la cuadrícula, pero no se extiende para rellenar el espacio disponible. Si la ventana es lo suficientemente grande, puede ver dos o más meses que se muestran a través del control hospedado MonthCalendar, pero se centran en la misma fila. El motor de diseño de WPF centra los elementos que no se pueden dimensionar para ocupar el espacio disponible.

Ampliación

A diferencia de los elementos de WPF, la mayoría de los controles de Windows Forms no son escalables continuamente. Para proporcionar el escalado personalizado, invalide el WindowsFormsHost.ScaleChild método .

Para escalar un control hospedado mediante el comportamiento predeterminado, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Scaling transformation. -->
    <StackPanel Grid.Row="0" Grid.Column="2">
      
      <StackPanel.RenderTransform>
        <ScaleTransform CenterX="0" CenterY="0" ScaleX="0.5" ScaleY="0.5" />
      </StackPanel.RenderTransform>
    
      <Label Content="A WPF UIElement" Background="OrangeRed"/>
      
      <WindowsFormsHost Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
      
      <Label Content="Another WPF UIElement" Background="OrangeRed"/>
      
    </StackPanel>
    
  2. Presione F5 para compilar y ejecutar la aplicación. El control hospedado y sus elementos circundantes se escalan por un factor de 0,5. Sin embargo, la fuente del control hospedado no se escala.

Rotante

A diferencia de los elementos de WPF, los controles de Windows Forms no admiten la rotación. El WindowsFormsHost elemento no gira con otros elementos WPF cuando se aplica una transformación de rotación. Cualquier valor de rotación distinto de 180 grados genera el LayoutError evento.

Para ver el efecto de la rotación en una aplicación híbrida, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Rotation transformation. -->
    <StackPanel Grid.Row="1" Grid.Column="2">
    
      <StackPanel.RenderTransform>
        <RotateTransform CenterX="200" CenterY="50" Angle="180" />
      </StackPanel.RenderTransform>
    
      <Label Content="A WPF element" Background="OrangeRed"/>
    
      <WindowsFormsHost Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    
      <Label Content="Another WPF element" Background="OrangeRed"/>
    
    </StackPanel>
    
  2. Presione F5 para compilar y ejecutar la aplicación. El control hospedado no gira, pero sus elementos circundantes giran por un ángulo de 180 grados. Es posible que tenga que cambiar el tamaño de la ventana para ver los elementos.

Establecer relleno y márgenes

El relleno y los márgenes en el diseño de WPF son similares al relleno y los márgenes en Windows Forms. Simplemente establezca las propiedades Padding y Margin en el elemento WindowsFormsHost.

Para establecer el relleno y los márgenes de un control hospedado, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Padding. -->
    <Canvas Grid.Row="2" Grid.Column="2">
      <WindowsFormsHost Padding="0, 20, 0, 0" Background="Yellow">
        <wf:Button Text="Windows Forms control with padding" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
    <!-- Margin. -->
    <Canvas Grid.Row="3" Grid.Column="2">
      <WindowsFormsHost Margin="20, 20, 0, 0" Background="Yellow">
        <wf:Button Text="Windows Forms control with margin" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. Presione F5 para compilar y ejecutar la aplicación. La configuración de relleno y margen se aplica a los controles hospedados de Windows Forms de la misma manera que se aplicarían en Windows Forms.

Uso de contenedores de diseño dinámico

Windows Forms proporciona dos contenedores de diseño dinámico y FlowLayoutPanelTableLayoutPanel. También puede usar estos contenedores en diseños de WPF.

Para usar un contenedor de diseño dinámico, siga estos pasos:

  1. Copie el código XAML siguiente en el Grid elemento :

    <!-- Flow layout. -->
    <DockPanel Grid.Row="4" Grid.Column="2">
      <WindowsFormsHost Name="flowLayoutHost" Background="Yellow">
        <wf:FlowLayoutPanel/>
      </WindowsFormsHost>
    </DockPanel>
    
  2. En MainWindow.xaml.vb o MainWindow.xaml.cs, copie el código siguiente en la definición de clase:

    private void InitializeFlowLayoutPanel()
    {
        System.Windows.Forms.FlowLayoutPanel flp =
            this.flowLayoutHost.Child as System.Windows.Forms.FlowLayoutPanel;
    
        flp.WrapContents = true;
    
        const int numButtons = 6;
    
        for (int i = 0; i < numButtons; i++)
        {
            System.Windows.Forms.Button b = new System.Windows.Forms.Button();
            b.Text = "Button";
            b.BackColor = System.Drawing.Color.AliceBlue;
            b.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
    
            flp.Controls.Add(b);
        }
    }
    
    Private Sub InitializeFlowLayoutPanel()
        Dim flp As System.Windows.Forms.FlowLayoutPanel = Me.flowLayoutHost.Child
    
        flp.WrapContents = True
    
        Const numButtons As Integer = 6
    
        Dim i As Integer
        For i = 0 To numButtons
            Dim b As New System.Windows.Forms.Button()
            b.Text = "Button"
            b.BackColor = System.Drawing.Color.AliceBlue
            b.FlatStyle = System.Windows.Forms.FlatStyle.Flat
    
            flp.Controls.Add(b)
        Next i
    
    End Sub
    
  3. Agregue una llamada al InitializeFlowLayoutPanel método en el constructor :

    public MainWindow()
    {
        InitializeComponent();
    
        this.InitializeFlowLayoutPanel();
    }
    
    Public Sub New()
        InitializeComponent()
    
        Me.InitializeFlowLayoutPanel()
    
    End Sub
    
  4. Presione F5 para compilar y ejecutar la aplicación. El WindowsFormsHost elemento rellena DockPanely FlowLayoutPanel organiza sus controles secundarios en el valor predeterminado FlowDirection.

Consulte también