Partager via


Procédure pas à pas : organisation de contrôles Windows Forms dans WPF

Cette procédure pas à pas vous montre comment utiliser les fonctionnalités de disposition WPF pour organiser des contrôles Windows Forms dans une application hybride.

Les tâches illustrées dans cette procédure pas à pas sont les suivantes :

  • Création du projet.
  • Utilisation des paramètres de disposition par défaut.
  • Dimensionnement du contenu.
  • Utilisation du positionnement absolu.
  • Spécification explicite de la taille.
  • Définition des propriétés de disposition.
  • Compréhension des limitations de l'ordre de plan.
  • Amarrage.
  • Paramétrage de la visibilité.
  • Hébergement d’un contrôle qui ne s'élargit pas.
  • Mise à l'échelle.
  • En rotation.
  • Définition de l'espacement et des marges.
  • Utilisation de conteneurs de disposition dynamique.

Pour obtenir une liste complète des tâches illustrées dans cette procédure pas à pas, consultez Organiser des contrôles Windows Forms dans l’exemple WPF.

Lorsque vous avez terminé, vous aurez une compréhension des fonctionnalités de disposition Windows Forms dans les applications WPF.

Conditions préalables

Vous avez besoin de Visual Studio pour effectuer cette procédure pas à pas.

Création du projet

Pour créer et configurer le projet, procédez comme suit :

  1. Créez un projet d’application WPF nommé WpfLayoutHostingWf.

  2. Dans l’Explorateur de solutions, ajoutez des références aux assemblys suivants :

    • WindowsFormsIntegration
    • System.Windows.Forms
    • System.Drawing
  3. Double-cliquez sur MainWindow.xaml pour l’ouvrir en mode XAML.

  4. Dans l’élément Window, ajoutez le mappage d’espace de noms Windows Forms suivant.

    xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    
  5. Dans l’élément Grid, définissez la propriété ShowGridLines sur true et définissez cinq lignes et trois colonnes.

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

Utilisation des paramètres de disposition par défaut

Par défaut, l’élément WindowsFormsHost gère la disposition du contrôle Windows Forms hébergé.

Pour utiliser les paramètres de disposition par défaut, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- Default layout. -->
    <Canvas Grid.Row="0" Grid.Column="0">
      <WindowsFormsHost Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. Appuyez sur F5 pour générer et exécuter l’application. Le contrôle System.Windows.Forms.Button Windows Forms apparaît dans le Canvas. Le contrôle hébergé est dimensionné en fonction de son contenu et l’élément WindowsFormsHost est dimensionné pour prendre en charge le contrôle hébergé.

Dimensionnement selon le contenu

L’élément WindowsFormsHost garantit que le contrôle hébergé est dimensionné pour afficher son contenu correctement.

Pour dimensionner le contenu, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- 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. Appuyez sur F5 pour générer et exécuter l’application. Les deux nouveaux contrôles de bouton sont dimensionnés pour afficher correctement la chaîne de texte plus longue et la taille de police supérieure, et les éléments WindowsFormsHost sont redimensionnés pour prendre en charge les contrôles hébergés.

Utilisation du positionnement absolu

Vous pouvez utiliser le positionnement absolu pour placer l’élément WindowsFormsHost n’importe où dans l’interface utilisateur.

Pour utiliser le positionnement absolu, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- 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. Appuyez sur F5 pour générer et exécuter l’application. L’élément WindowsFormsHost est placé à 20 pixels du côté supérieur de la cellule de grille et à 20 pixels du côté gauche.

Spécification explicite de la taille

Vous pouvez spécifier la taille de l’élément WindowsFormsHost à l’aide des propriétés Width et Height.

Pour spécifier explicitement la taille, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- 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. Appuyez sur F5 pour générer et exécuter l’application. L’élément WindowsFormsHost est défini sur une taille de 50 pixels de large de 70 pixels de haut, ce qui est inférieur aux paramètres de disposition par défaut. Le contenu du contrôle Windows Forms est réorganisé en conséquence.

Configuration des propriétés de mise en page

Définissez toujours les propriétés liées à la disposition sur le contrôle hébergé à l’aide des propriétés de l’élément WindowsFormsHost. La définition des propriétés de disposition directement sur le contrôle hébergé génère des résultats inattendus.

La définition des propriétés liées à la disposition sur le contrôle hébergé en XAML n’a aucun effet.

Pour afficher les effets de la définition des propriétés sur le contrôle hébergé, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- 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. Dans explorateur de solutions, double-cliquez sur MainWindow.xaml.vb ou MainWindow.xaml.cs pour l’ouvrir dans l’éditeur de code.

  3. Copiez le code suivant dans la définition de classe 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. Appuyez sur F5 pour générer et exécuter l’application.

  5. Cliquez sur le bouton Cliquez sur moi. Le gestionnaire d’événements button1_Click définit les propriétés Top et Left sur le contrôle hébergé. Cela entraîne le repositionnement du contrôle hébergé dans l’élément WindowsFormsHost. L’hôte gère la même zone d’écran, mais le contrôle hébergé est clippé. Au lieu de cela, le contrôle hébergé doit toujours remplir l’élément WindowsFormsHost.

Comprendre les limitations de l'ordre Z

Les éléments WindowsFormsHost visibles sont toujours affichés au-dessus des autres éléments WPF, car ils ne sont pas affectés par l'ordre de plan. Pour voir ce comportement z-order, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- 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. Appuyez sur F5 pour générer et exécuter l’application. L'élément WindowsFormsHost est superposé à l'élément label.

Amarrage

L'élément WindowsFormsHost prend en charge l’ancrage WPF. Définissez la propriété jointe Dock pour ancrer le contrôle hébergé dans un élément DockPanel.

Pour ancrer un contrôle hébergé, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- 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. Appuyez sur F5 pour générer et exécuter l’application. L’élément WindowsFormsHost est ancré à droite de l’élément DockPanel.

Paramétrage de la visibilité

Vous pouvez rendre votre contrôle Windows Forms invisible ou le réduire en définissant la propriété Visibility sur l’élément WindowsFormsHost. Lorsqu’un contrôle est invisible, il n’est pas affiché, mais il occupe l’espace de disposition. Lorsqu’un contrôle est réduit, il n’est pas affiché et n’occupe pas d’espace.

Pour définir la visibilité d’un contrôle hébergé, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- 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. Dans MainWindow.xaml.vb ou MainWindow.xaml.cs, copiez le code suivant dans la définition de classe :

    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. Appuyez sur F5 pour générer et exécuter l’application.

  4. Cliquez sur le bouton Click to make invisible pour rendre l'élément WindowsFormsHost invisible.

  5. Cliquez sur le bouton Cliquez pour réduire pour masquer entièrement l’élément WindowsFormsHost de la mise en page. Lorsque le contrôle Windows Forms est réduit, les éléments environnants sont réorganisés pour occuper son espace.

Héberger un élément de contrôle qui ne s'élargit pas

Certains contrôles Windows Forms ont une taille fixe et ne s’étendent pas pour remplir l’espace disponible dans la disposition. Par exemple, le contrôle MonthCalendar affiche un mois dans un espace fixe.

Pour héberger un contrôle qui n’est pas étendu, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- 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. Appuyez sur F5 pour générer et exécuter l’application. L’élément WindowsFormsHost est centré dans la ligne de grille, mais il n’est pas étiré pour remplir l’espace disponible. Si la fenêtre est suffisamment grande, vous pouvez voir deux mois ou plus affichés par le contrôle de MonthCalendar hébergé, mais ceux-ci sont centrés dans la ligne. Le moteur de disposition WPF centre les éléments qui ne peuvent pas être dimensionnés pour remplir l’espace disponible.

Mise à l'échelle

Contrairement aux éléments WPF, la plupart des contrôles Windows Forms ne sont pas évolutifs en continu. Pour fournir une mise à l’échelle personnalisée, vous remplacez la méthode WindowsFormsHost.ScaleChild.

Pour mettre à l’échelle un contrôle hébergé à l’aide du comportement par défaut, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- 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. Appuyez sur F5 pour générer et exécuter l’application. Le contrôle hébergé et ses éléments environnants sont mis à l’échelle par un facteur de 0,5. Toutefois, la police du contrôle hébergé n’est pas mise à l’échelle.

Rotatif

Contrairement aux éléments WPF, les contrôles Windows Forms ne prennent pas en charge la rotation. L'élément WindowsFormsHost ne pivote pas avec d'autres éléments WPF lorsqu'une transformation de rotation est appliquée. Toute valeur de rotation autre que 180 degrés déclenche l’événement LayoutError.

Pour voir l’effet de la rotation dans une application hybride, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- 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. Appuyez sur F5 pour générer et exécuter l’application. Le contrôle hébergé n’est pas pivoté, mais ses éléments environnants sont pivotés par un angle de 180 degrés. Vous devrez peut-être redimensionner la fenêtre pour afficher les éléments.

Définition de l'espacement et des marges

Le remplissage et les marges dans la disposition WPF sont similaires au remplissage et aux marges dans Windows Forms. Définissez simplement les propriétés Padding et Margin sur l’élément WindowsFormsHost.

Pour définir le remplissage et les marges d’un contrôle hébergé, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- 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. Appuyez sur F5 pour générer et exécuter l’application. Les paramètres de remplissage et de marge sont appliqués aux contrôles Windows Forms hébergés de la même façon qu’ils seront appliqués dans Windows Forms.

Utilisation de conteneurs de disposition dynamique

Windows Forms fournit deux conteneurs de disposition dynamique, FlowLayoutPanel et TableLayoutPanel. Vous pouvez également utiliser ces conteneurs dans les dispositions WPF.

Pour utiliser un conteneur de disposition dynamique, procédez comme suit :

  1. Copiez le code XAML suivant dans l’élément Grid :

    <!-- Flow layout. -->
    <DockPanel Grid.Row="4" Grid.Column="2">
      <WindowsFormsHost Name="flowLayoutHost" Background="Yellow">
        <wf:FlowLayoutPanel/>
      </WindowsFormsHost>
    </DockPanel>
    
  2. Dans MainWindow.xaml.vb ou MainWindow.xaml.cs, copiez le code suivant dans la définition de classe :

    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. Ajoutez un appel à la méthode InitializeFlowLayoutPanel dans le constructeur :

    public MainWindow()
    {
        InitializeComponent();
    
        this.InitializeFlowLayoutPanel();
    }
    
    Public Sub New()
        InitializeComponent()
    
        Me.InitializeFlowLayoutPanel()
    
    End Sub
    
  4. Appuyez sur F5 pour générer et exécuter l’application. L’élément WindowsFormsHost remplit le DockPanelet FlowLayoutPanel organise ses contrôles enfants dans la FlowDirectionpar défaut.

Voir aussi