Wskazówki: rozmieszczanie formantów Windows Forms w WPF

W tym przewodniku pokazano, jak używać funkcji układu WPF do rozmieszczania kontrolek Windows Forms w aplikacji hybrydowej.

Zadania przedstawione w tym przewodniku obejmują:

  • Tworzenie projektu.
  • Przy użyciu domyślnych ustawień układu.
  • Ustalanie rozmiaru do zawartości.
  • Używanie pozycjonowania bezwzględnego.
  • Jawne określanie rozmiaru.
  • Ustawianie właściwości układu.
  • Informacje o ograniczeniach zamówień z.
  • Dokowania.
  • Ustawianie widoczności.
  • Hostowanie kontrolki, która nie rozciąga się.
  • Skalowanie.
  • Obrotowa.
  • Ustawianie dopełnienia i marginesów.
  • Używanie kontenerów układu dynamicznego.

Aby uzyskać pełną listę kodu zadań przedstawionych w tym przewodniku, zobacz Rozmieszczanie kontrolek formularzy systemu Windows w przykładzie WPF.

Po zakończeniu będziesz mieć wiedzę na temat funkcji układu formularzy systemu Windows w aplikacjach opartych na WPF.

Wymagania wstępne

Aby ukończyć ten przewodnik, potrzebny jest program Visual Studio.

Tworzenie projektu

Aby utworzyć i skonfigurować projekt, wykonaj następujące kroki:

  1. Utwórz projekt aplikacji WPF o nazwie WpfLayoutHostingWf.

  2. W Eksplorator rozwiązań dodaj odwołania do następujących zestawów:

    • WindowsFormsIntegration
    • System.Windows.Forms
    • System.drawing
  3. Kliknij dwukrotnie plik MainWindow.xaml , aby otworzyć go w widoku XAML.

  4. W elememencie Window dodaj następujące mapowanie przestrzeni nazw formularzy systemu Windows.

    xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    
  5. W elemecie Grid ustaw ShowGridLines właściwość na true wartość i zdefiniuj pięć wierszy i trzy kolumny.

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

Korzystanie z Ustawienia układu domyślnego

Domyślnie WindowsFormsHost element obsługuje układ hostowanej kontrolki Windows Forms.

Aby użyć domyślnych ustawień układu, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- Default layout. -->
    <Canvas Grid.Row="0" Grid.Column="0">
      <WindowsFormsHost Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację. Kontrolka Formularze systemu System.Windows.Forms.Button Windows jest wyświetlana w elememencie Canvas. Rozmiar hostowanej kontrolki zależy od jego zawartości, a WindowsFormsHost rozmiar elementu jest odpowiedni do obsługi hostowanej kontrolki.

Ustalanie rozmiaru do zawartości

Element zapewnia, że hostowana kontrolka WindowsFormsHost ma prawidłowy rozmiar, aby wyświetlić jego zawartość.

Aby rozmiar zawartości był większy, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- 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. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację. Dwa nowe kontrolki przycisku mają rozmiar umożliwiający prawidłowe wyświetlanie dłuższego ciągu tekstowego i większego rozmiaru czcionki, a WindowsFormsHost rozmiar elementów jest zmieniany w celu dostosowania ich do hostowanych kontrolek.

Używanie pozycjonowania bezwzględnego

Możesz użyć pozycjonowania bezwzględnego, aby umieścić WindowsFormsHost element w dowolnym miejscu w interfejsie użytkownika.

Aby użyć pozycjonowania bezwzględnego, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- 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. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację. Element WindowsFormsHost jest umieszczony 20 pikseli z górnej strony komórki siatki i 20 pikseli po lewej stronie.

Jawne określanie rozmiaru

Rozmiar elementu można określić WindowsFormsHost przy użyciu Width właściwości i Height .

Aby jawnie określić rozmiar, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- 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. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację. Element WindowsFormsHost jest ustawiony na rozmiar 50 pikseli szerokości o wysokości 70 pikseli, który jest mniejszy niż domyślne ustawienia układu. Zawartość kontrolki Windows Forms jest odpowiednio zmieniana.

Ustawianie właściwości układu

Zawsze ustawiaj właściwości związane z układem w hostowanej kontrolce przy użyciu właściwości WindowsFormsHost elementu. Ustawienie właściwości układu bezpośrednio w hostowanej kontrolce spowoduje uzyskanie niezamierzonych wyników.

Ustawienie właściwości związanych z układem w hostowanej kontrolce w języku XAML nie ma wpływu.

Aby zobaczyć wpływ ustawień właściwości hostowanej kontrolki, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- 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. W Eksplorator rozwiązań kliknij dwukrotnie plik MainWindow.xaml.vb lub MainWindow.xaml.cs, aby otworzyć go w Edytorze kodu.

  3. Skopiuj następujący kod do MainWindow definicji klasy:

    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. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację.

  5. Kliknij przycisk Kliknij mnie. Program button1_Click obsługi zdarzeń ustawia Top właściwości i Left w hostowanej kontrolce. Powoduje to zmiana położenia hostowanej kontrolki w elemecie WindowsFormsHost . Host utrzymuje ten sam obszar ekranu, ale hostowana kontrolka jest obcięta. Zamiast tego hostowana kontrolka powinna zawsze wypełniać WindowsFormsHost element.

Opis ograniczeń zamówienia Z

Widoczne WindowsFormsHost elementy są zawsze rysowane na górze innych elementów WPF i nie mają wpływu na kolejność z. Aby wyświetlić to zachowanie w kolejności z, wykonaj następujące czynności:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- 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. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację. Element WindowsFormsHost jest malowany na elemecie label.

Dokowania

WindowsFormsHost Element obsługuje dokowanie WPF. Ustaw dołączoną właściwość, Dock aby zadokować hostowaną kontrolkę w elemecie DockPanel .

Aby zadokować hostowaną kontrolkę, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- 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. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację. Element WindowsFormsHost jest zadokowany po prawej stronie DockPanel elementu.

Ustawianie widoczności

Kontrolkę Formularzy systemu Windows można ustawić jako niewidoczną lub zwijać, ustawiając Visibility właściwość elementu WindowsFormsHost . Gdy kontrolka jest niewidoczna, nie jest wyświetlana, ale zajmuje miejsce w układzie. Gdy kontrolka jest zwinięta, nie jest wyświetlana ani nie zajmuje miejsca w układzie.

Aby ustawić widoczność hostowanej kontrolki, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- 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. W pliku MainWindow.xaml.vb lub MainWindow.xaml.cs skopiuj następujący kod do definicji klasy:

    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. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację.

  4. Kliknij przycisk Kliknij, aby niewidoczny, aby element był WindowsFormsHost niewidoczny.

  5. Kliknij przycisk Kliknij, aby zwinąć, aby całkowicie ukryć WindowsFormsHost element w układzie. Gdy kontrolka Windows Forms jest zwinięta, otaczające elementy są zmieniane tak, aby zajmowały miejsce.

Hostowanie kontrolki, która nie rozciąga się

Niektóre kontrolki Windows Forms mają stały rozmiar i nie rozciągają się, aby wypełnić dostępne miejsce w układzie. Na przykład kontrolka MonthCalendar wyświetla miesiąc w stałym miejscu.

Aby hostować kontrolkę, która nie rozciąga się, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- 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. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację. Element WindowsFormsHost jest wyśrodkowany w wierszu siatki, ale nie jest rozproszony, aby wypełnić dostępne miejsce. Jeśli okno jest wystarczająco duże, może zostać wyświetlone co najmniej dwa miesiące przez hostowaną MonthCalendar kontrolkę, ale są one wyśrodkowane w wierszu. Aparat układu WPF wyśrodkuje elementy, których rozmiar nie może mieć rozmiaru, aby wypełnić dostępne miejsce.

Skalowanie

W przeciwieństwie do elementów WPF większość kontrolek Windows Forms nie jest stale skalowalna. Aby zapewnić niestandardowe skalowanie, należy zastąpić metodę WindowsFormsHost.ScaleChild .

Aby skalować hostowaną kontrolkę przy użyciu domyślnego zachowania, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- 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. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację. Hostowana kontrolka i jego otaczające elementy są skalowane przez współczynnik 0,5. Jednak czcionka hostowanej kontrolki nie jest skalowana.

Obrotowa

W przeciwieństwie do elementów WPF kontrolki Windows Forms nie obsługują rotacji. Element WindowsFormsHost nie obraca się z innymi elementami WPF po zastosowaniu przekształcenia obrotu. Każda wartość obrotu inna niż 180 stopni podnosi LayoutError zdarzenie.

Aby zobaczyć efekt rotacji w aplikacji hybrydowej, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- 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. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację. Kontrolka hostowana nie jest obracana, ale jego otaczające elementy są obracane kątem 180 stopni. Aby wyświetlić elementy, może być konieczne zmianę rozmiaru okna.

Ustawianie dopełnienia i marginesów

Wypełnienie i marginesy w układzie WPF są podobne do wypełnienia i marginesów w formularzach Windows Forms. Wystarczy ustawić Padding właściwości i Margin dla WindowsFormsHost elementu .

Aby ustawić dopełnienie i marginesy dla hostowanej kontrolki, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- 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. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację. Ustawienia uzupełniania i marginesu są stosowane do hostowanych kontrolek Windows Forms w taki sam sposób, jak w formularzach systemu Windows.

Używanie kontenerów układu dynamicznego

Formularze systemu Windows udostępniają dwa kontenery układu dynamicznego i FlowLayoutPanelTableLayoutPanel. Tych kontenerów można również używać w układach WPF.

Aby użyć kontenera układu dynamicznego, wykonaj następujące kroki:

  1. Skopiuj następujący kod XAML do Grid elementu :

    <!-- Flow layout. -->
    <DockPanel Grid.Row="4" Grid.Column="2">
      <WindowsFormsHost Name="flowLayoutHost" Background="Yellow">
        <wf:FlowLayoutPanel/>
      </WindowsFormsHost>
    </DockPanel>
    
  2. W pliku MainWindow.xaml.vb lub MainWindow.xaml.cs skopiuj następujący kod do definicji klasy:

    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. Dodaj wywołanie metody InitializeFlowLayoutPanel w konstruktorze:

    public MainWindow()
    {
        InitializeComponent();
    
        this.InitializeFlowLayoutPanel();
    }
    
    Public Sub New()
        InitializeComponent()
    
        Me.InitializeFlowLayoutPanel()
    
    End Sub
    
  4. Naciśnij klawisz F5, aby skompilować i uruchomić aplikację. Element WindowsFormsHost wypełnia kontrolki DockPanel, i FlowLayoutPanel rozmieszcza kontrolki podrzędne w domyślnym elemecie FlowDirection.

Zobacz też