Поделиться через


Пошаговое руководство. Упорядочение элементов управления Windows Forms в приложении WPF

В этом пошаговом руководстве показано, как использовать функции макета WPF для упорядочения элементов управления Windows Forms в гибридном приложении.

В данном пошаговом руководстве представлены следующие задачи.

  • Создание проекта.
  • Использование параметров макета по умолчанию.
  • Изменение размеров в зависимости от содержимого.
  • Использование абсолютного позиционирования.
  • Задание размера явным образом.
  • Установка свойств макета.
  • Описание ограничений z-порядка.
  • Закрепление.
  • Задание видимости.
  • Размещение нерастягиваемых элементов управления.
  • Масштабирование.
  • Поворот.
  • Задание полей и внутренних полей.
  • Использование динамических контейнеров макета.

Полный пример кода для задач, демонстрируемых в этом пошаговом руководстве, см. в разделе Пример упорядочения элементов управления Windows Forms в WPF.

По окончании знакомства с разделом пользователь будет иметь представление о возможностях макета Windows Forms в приложениях, основанных на WPF.

Необходимые компоненты

Для выполнения шагов, описанных в этом руководстве, вам понадобится Visual Studio.

Создание проекта

Чтобы создать и настроить проект, выполните следующие действия.

  1. Создайте проект приложения WPF с именем WpfLayoutHostingWf.

  2. В обозревателе решений добавьте ссылки на следующие сборки.

    • WindowsFormsIntegration
    • System.Windows.Forms.
    • System.Drawing;
  3. Дважды щелкните файл MainWindow.xaml, чтобы открыть его в представлении XAML.

  4. В элемент Window добавьте следующее сопоставление пространства имен Windows Forms.

    xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    
  5. В элементе Grid задайте свойству ShowGridLines значение true и определите пять строк и три столбца.

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

Использование параметров макета по умолчанию

По умолчанию элемент WindowsFormsHost обрабатывает макет размещенного элемента управления Windows Forms.

Чтобы использовать параметры макета по умолчанию, выполните следующие действия.

  1. Скопируйте следующий код XAML в элемент Grid.

    <!-- Default layout. -->
    <Canvas Grid.Row="0" Grid.Column="0">
      <WindowsFormsHost Background="Yellow">
        <wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Canvas>
    
  2. Нажмите клавишу F5 для сборки и запуска приложения. Элемент управления Windows Forms System.Windows.Forms.Button отображается в элементе Canvas. Размер размещенного элемента управления основан на его содержимом, а размеры элемента управления WindowsFormsHost изменяются, чтобы вместить размещенный элемент управления.

Изменение размеров в соответствии с содержимым

Элемент WindowsFormsHost гарантирует, что размер размещенного элемента управления регулируется для правильного отображения его содержимого.

Чтобы изменить размер содержимого, выполните следующие действия.

  1. Скопируйте следующий код XAML в элемент 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. Нажмите клавишу F5 для сборки и запуска приложения. Размер двух новых кнопок корректно изменяется для отображения длинных строк текста и большого шрифта, а размер элементов WindowsFormsHost изменяется, чтобы вместить размещенные элементы управления.

Использование абсолютного позиционирования

Можно использовать абсолютное позиционирование, чтобы разместить элемент WindowsFormsHost в любом месте интерфейса пользователя.

Чтобы использовать абсолютное позиционирование, выполните следующие действия.

  1. Скопируйте следующий код XAML в элемент 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. Нажмите клавишу F5 для сборки и запуска приложения. Элемент WindowsFormsHost размещается в 20 точках от верхнего края ячейки сетки и в 20 точках от левого края.

Задание размера явным образом

Можно указать размер элемента WindowsFormsHost с помощью свойств Width и Height.

Чтобы указать размер явно, сделайте следующее.

  1. Скопируйте следующий код XAML в элемент 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. Нажмите клавишу F5 для сборки и запуска приложения. Размер элемента WindowsFormsHost устанавливается в 50 точек в ширину и в 70 точек в высоту — это меньше, чем параметры макета по умолчанию. Содержимое элемента управления Windows Forms упорядочивается соответствующим образом.

Установка свойств макета

Всегда следует задавать связанные с макетом свойства для размещенного элемента управления с помощью свойств элемента WindowsFormsHost. При установке свойств макета непосредственно для размещаемого элемента управления результат не будет соответствовать ожидаемому.

Установка связанных с макетом свойств размещенного элемента управления в XAML не оказывает никакого действия.

Чтобы увидеть влияние задания свойств размещенного элемента управления, выполните следующие шаги.

  1. Скопируйте следующий код XAML в элемент 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. В обозревателе решений дважды щелкните файл MainWindow.xaml.vb или MainWindow.xaml.cs, чтобы открыть его в редакторе кода.

  3. Скопируйте следующий код в определение класса 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. Нажмите клавишу F5 для сборки и запуска приложения.

  5. Нажмите кнопку Click me. Обработчик событий button1_Click задает свойства Top и Left свойства размещенного элемента управления. Это вызывает изменение позиции размещенного элемента управления внутри элемента WindowsFormsHost. Ведущий элемент занимает то же пространство на экране, но размещаемый элемент управления обрезается. Напротив, размещенный элемент управления всегда должен заполнять элемент WindowsFormsHost.

Описание ограничений z-порядка

Видимые элементы WindowsFormsHost всегда отрисовываются в верхней части элементов WPF и к ним неприменимо свойство z-order. Это поведение свойства z-order можно продемонстрировать на следующем примере.

  1. Скопируйте следующий код XAML в элемент 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. Нажмите клавишу F5 для сборки и запуска приложения. Элемент WindowsFormsHost отрисовывается над элементом метки.

Закрепление

Элемент WindowsFormsHost поддерживает закрепление WPF. Задайте присоединенное свойство Dock для закрепления размещенного элемента в элементе управления DockPanel.

Чтобы закрепить размещенный элемент управления, выполните следующие действия.

  1. Скопируйте следующий код XAML в элемент 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. Нажмите клавишу F5 для сборки и запуска приложения. Элемент управления WindowsFormsHost закреплен в правой части элемента управления DockPanel.

Задание видимости

Элемент управления Windows Forms можно сделать невидимым или свернуть его, задав значение свойству Visibility элемента управления WindowsFormsHost. Если элемент управления невидим, он не отображается, но при этом занимает пространство разметки. Если элемент управления свернут, он не отображается и не занимает пространство разметки.

Для задания видимости размещенного элемента управления выполните следующие шаги.

  1. Скопируйте следующий код XAML в элемент 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. В файле MainWindow.xaml.vb или MainWindow.xaml.cs скопируйте следующий код в определение класса.

    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. Нажмите клавишу F5 для сборки и запуска приложения.

  4. Щелкните кнопку Щелкните для невидимости, чтобы элемент управления WindowsFormsHost стал невидимым.

  5. Щелкните кнопку Щелкните, чтобы свернуть для того, чтобы полностью скрыть элемент управления WindowsFormsHost на макете. Когда элемент управления Windows Forms свернут, соседние элементы переупорядочиваются, чтобы занять его место.

Размещение нерастягиваемых элементов управления

Некоторые элементы управления Windows Forms имеют фиксированный размер и не растягиваются для заполнения доступного места в макете. Например, элемент управления MonthCalendar отображает значение месяца в ограниченном пространстве.

Для размещения нерастягиваемого элемента управления выполните следующие шаги.

  1. Скопируйте следующий код XAML в элемент 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. Нажмите клавишу F5 для сборки и запуска приложения. Элемент управления WindowsFormsHost центруется по строке сетки, но не растягивается, чтобы занять все доступное место. Если окно достаточно большое, можно увидеть два или более месяцев, отображаемых размещенным элементом управления MonthCalendar, но они выравниваются по центру строки. Обработчик макета WPF выравнивает по центру элементы, размеры которых не меняются для заполнения доступного пространства.

Масштабирование

В отличие от элементов управления WPF, большинство элементов управления Windows Forms не являются непрерывно масштабируемыми. Чтобы обеспечить пользовательское масштабирование, переопределите метод WindowsFormsHost.ScaleChild.

Чтобы выполнить масштабирование размещенного элемента управления с помощью поведения по умолчанию, выполните следующие шаги.

  1. Скопируйте следующий код XAML в элемент 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. Нажмите клавишу F5 для сборки и запуска приложения. Размещаемый элемент управления и его окружающие элементы масштабируются с коэффициентом 0,5. Но шрифт размещаемого элемента управления не масштабируется.

Поворот

В отличие от элементов WPF, элементы управления Windows Forms не поддерживают поворот. Элемент управления WindowsFormsHost не будет поворачиваться совместно с другими элементами управления WPF после применения преобразования поворота. Поворот на величину градуса, отличную от 180, вызывает событие LayoutError.

Чтобы увидеть эффект от поворота в гибридном приложении, выполните следующие действия.

  1. Скопируйте следующий код XAML в элемент 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. Нажмите клавишу F5 для сборки и запуска приложения. Размещаемый элемент управления не повернут, но его соседние элементы повернуты на угол в 180 градусов. Для отображения элементов может потребоваться изменить размер окна.

Задание отбивки и внутренних полей

Отбивка и внутренние поля в макете WPF похожи на свои аналоги в Windows Forms. Просто задайте свойства Padding и Margin элемента WindowsFormsHost.

Для задания отбивки и внутренних полей размещенного элемента управления, выполните следующие шаги.

  1. Скопируйте следующий код XAML в элемент 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. Нажмите клавишу F5 для сборки и запуска приложения. Параметры отбивки и внутренних полей будут применены к размещенным элементам управления Windows Forms так же, как и в Windows Forms.

Использование динамических контейнеров макета

Windows Forms предоставляет два контейнера динамического макета: FlowLayoutPanel и TableLayoutPanel. Можно также использовать эти контейнеры в макетах WPF.

Чтобы использовать контейнер динамического макета, выполните следующие действия.

  1. Скопируйте следующий код XAML в элемент Grid.

    <!-- Flow layout. -->
    <DockPanel Grid.Row="4" Grid.Column="2">
      <WindowsFormsHost Name="flowLayoutHost" Background="Yellow">
        <wf:FlowLayoutPanel/>
      </WindowsFormsHost>
    </DockPanel>
    
  2. В файле MainWindow.xaml.vb или MainWindow.xaml.cs скопируйте следующий код в определение класса.

    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. Добавьте вызов метода InitializeFlowLayoutPanel в конструктор.

    public MainWindow()
    {
        InitializeComponent();
    
        this.InitializeFlowLayoutPanel();
    }
    
    Public Sub New()
        InitializeComponent()
    
        Me.InitializeFlowLayoutPanel()
    
    End Sub
    
  4. Нажмите клавишу F5 для сборки и запуска приложения. Элемент WindowsFormsHost заполняет элемент DockPanel, а FlowLayoutPanel упорядочивает его дочерние элементы управления согласно значению свойства FlowDirection по умолчанию.

См. также