Udostępnij za pośrednictwem


Przewodnik: rozmieszczanie kontrolek formularzy systemu Windows 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.
  • Dopasowywanie rozmiaru do zawartości.
  • Używanie pozycjonowania bezwzględnego.
  • Jawne określanie rozmiaru.
  • Ustawianie właściwości układu.
  • Zrozumienie ograniczeń porządku warstw.
  • Dokowanie.
  • Ustawianie widoczności.
  • Umieszczenie kontrolki, która się nie rozciąga.
  • Skalowanie.
  • Obracanie.
  • Ustawianie wypeł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 Eksploratorze 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 elemencie Grid ustaw właściwość ShowGridLines na true 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>
    

Używanie domyślnych ustawień układu

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 F5, aby skompilować i uruchomić aplikację. Kontrolka Windows Forms System.Windows.Forms.Button pojawia się w elemencie Canvas. Rozmiar hostowanej kontrolki zależy od jej zawartości, a element WindowsFormsHost jest wymiarowany tak, aby pomieścić hostowaną kontrolkę.

Dopasowanie rozmiaru do zawartości

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

Aby dopasować rozmiar do zawartości, 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 F5, aby skompilować i uruchomić aplikację. Dwa nowe kontrolki przycisków są dostosowane tak, aby prawidłowo wyświetlać dłuższy tekst oraz większą czcionkę, a elementy WindowsFormsHost są odpowiednio zmieniane, aby pomieścić hostowane kontrolki.

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 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 WindowsFormsHost można określić przy użyciu właściwości Width 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 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 Eksploratorze rozwiązań kliknij dwukrotnie 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 F5, aby skompilować i uruchomić aplikację.

  5. Kliknij przycisk Kliknij mnie . Procedura button1_Click obsługi zdarzeń ustawia właściwości Top 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.

Zrozumienie ograniczeń porządku 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 warstw, wykonaj te kroki:

  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 F5, aby skompilować i uruchomić aplikację. Element WindowsFormsHost jest malowany nad elementem label.

Dokowanie

WindowsFormsHost Element obsługuje dokowanie WPF. Ustaw właściwość dołączoną Dock aby zadokować hostowaną kontrolkę w elemencie 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 F5, aby skompilować i uruchomić aplikację. Element WindowsFormsHost jest zadokowany po prawej stronie elementu DockPanel.

Ustawianie widoczności

Kontrolkę formularzy systemu Windows można ustawić jako niewidoczną lub zwinąć, ustawiając właściwość elementu Visibility na 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 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 F5, aby skompilować i uruchomić aplikację.

  4. Kliknij przycisk Kliknij, aby uczynić niewidocznym, aby element WindowsFormsHost był niewidoczny.

  5. Kliknij przycisk Kliknij, aby zwinąć, aby całkowicie ukryć element WindowsFormsHost 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 umieścić kontrolkę, która się nie rozciąga, 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 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, przez hostowaną MonthCalendar kontrolkę mogą zostać wyświetlone dwa lub więcej miesięcy, ale są one wyśrodkowane w wierszu. Mechanizm układu WPF wyśrodkowuje elementy, które nie mogą zostać dostosowane do wypełnienia dostępnego miejsca.

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

Obracanie się

W przeciwieństwie do elementów WPF kontrolki Windows Forms nie obsługują rotacji. Element WindowsFormsHost nie obraca się wraz z innymi elementami WPF, gdy zastosowane jest przekształcenie obrotu. Każda wartość obrotu inna niż 180 stopni wywołuje zdarzenie LayoutError.

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

Ustawianie wypeł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ć właściwości Padding i Margin na elemencie WindowsFormsHost.

Aby ustawić wypeł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 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: FlowLayoutPanel i TableLayoutPanel. 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 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 F5, aby skompilować i uruchomić aplikację. Element WindowsFormsHost wypełnia DockPanel, a FlowLayoutPanel rozmieszcza swoje kontrolki podrzędne w domyślnym elemencie FlowDirection.

Zobacz także