Прочитать на английском

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


Пошаговое руководство. Упорядочение элементов управления 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.

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

    XAML
    <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:

    XAML
    <!-- 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:

    XAML
    <!-- 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:

    XAML
    <!-- 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:

    XAML
    <!-- 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:

    XAML
    <!-- 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:

    C#
    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;
    }
    
  4. Нажмите клавишу F5, чтобы создать и запустить приложение.

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

Общие сведения об ограничениях Z-order

Видимые элементы WindowsFormsHost всегда рисуются поверх других элементов WPF и не зависят от порядка z. Чтобы увидеть, как работает порядок сортировки по оси Z, сделайте следующее:

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

    XAML
    <!-- 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 размещён поверх элемента label.

Стыковка

элемент WindowsFormsHost поддерживает докинг в WPF. Установите присоединенное свойство Dock, чтобы закрепить управляющий элемент в элементе DockPanel.

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

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

    XAML
    <!-- 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:

    XAML
    <!-- 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скопируйте следующий код в определение класса:

    C#
    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;
    }
    
  3. Нажмите клавишу F5, чтобы создать и запустить приложение.

  4. Нажмите кнопку Click, чтобы сделать невидимым кнопку, чтобы сделать элемент WindowsFormsHost невидимым.

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

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

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

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

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

    XAML
    <!-- 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:

    XAML
    <!-- 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:

    XAML
    <!-- 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:

    XAML
    <!-- 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>
    
    XAML
    <!-- 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:

    XAML
    <!-- 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скопируйте следующий код в определение класса:

    C#
    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);
        }
    }
    
  3. Добавьте вызов метода InitializeFlowLayoutPanel в конструкторе:

    C#
    public MainWindow()
    {
        InitializeComponent();
    
        this.InitializeFlowLayoutPanel();
    }
    
  4. Нажмите клавишу F5, чтобы создать и запустить приложение. Элемент WindowsFormsHost заполняет DockPanel, а FlowLayoutPanel упорядочивает дочерние элементы управления в умолчании FlowDirection.

См. также