Обзор: размещение элементов управления Windows Presentation Foundation в приложении Windows Forms
Обновлен: Ноябрь 2007
В этом пошаговом руководстве демонстрируется использование возможностей макета WPF для упорядочения элементов управления Windows Forms в гибридных приложениях.
В этом пошаговом руководстве, в частности, рассматриваются следующие задачи:
Создание проекта.
Использование параметров макета по умолчанию.
Изменение размеров в зависимости от содержимого.
Использование абсолютного позиционирования.
Задание размера явным образом.
Установка свойств макета.
Описание ограничений z-порядка.
Закрепление.
Задание видимости.
Размещение нерастягиваемых элементов управления.
Масштабирование.
Поворот.
Задание полей и внутренних полей.
Использование динамических контейнеров макета.
Полный пример кода для задач, приведенных в этом пошаговом руководстве, см. в разделе Пример упорядочивания элементов управления Windows Forms в Windows Presentation Foundation.
По окончании знакомства с разделом пользователь будет иметь представление о возможностях макета Windows Forms в приложениях, основанных на WPF.
![]() |
---|
Отображаемые диалоговые окна и команды меню могут отличаться от описанных в справке, в зависимости от действующих параметров или версии среды. Чтобы изменить параметры, выберите в меню Сервис команду Импорт и экспорт параметров. Дополнительные сведения см. в разделе Параметры Visual Studio. |
Обязательные компоненты
Для выполнения инструкций данного пошагового руководства необходимы следующие компоненты.
- Visual Studio 2008.
Создание проекта
Чтобы создать и настроить проект
Создайте проект приложения WPF с именем WpfLayoutHostingWf.
В обозревателе решений добавьте ссылку на сборку WindowsFormsIntegration с именем WindowsFormsIntegration.dll.
В обозревателе решений добавьте ссылку на сборку System.Windows.Forms с именем System.Windows.Forms.dll. Добавьте ссылку на сборку System.Drawing, которая называется System.Drawing.dll.
Дважды щелкните Window1.xaml, чтобы открыть его в XAML представлении.
В начале файла добавьте пространство имен Windows Forms со следующим кодом.
<Window x:Class="Window1" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" Title="Layout Demo for Interoperability" >
<Window x:Class="WpfLayoutHostingWfWithXaml.Window1" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" Title="Layout Demo for Interoperability" >
Задайте элемент Grid по умолчанию путем создания трех столбцов и пяти строк.
<Grid ShowGridLines="True"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions>
<Grid ShowGridLines="true"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions>
Использование параметров макета по умолчанию
По умолчанию элемент WindowsFormsHost обрабатывает макет для размещаемого элемента управления Windows Forms.
Для использования параметров макета по умолчанию
Скопируйте следующий код в элемент Grid.
<!-- Default layout. --> <Canvas Grid.Row="0" Grid.Column="0"> <WindowsFormsHost Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> </Canvas>
<!-- Default layout. --> <Canvas Grid.Row="0" Grid.Column="0"> <WindowsFormsHost Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> </Canvas>
Нажмите клавишу F5 для построения и выполнения приложения. Элемент управления Windows FormsSystem.Windows.Forms.Button находится внутри элемента управления Canvas. Размер размещаемого элемента управления основан на его содержимом, а размеры элемента управления WindowsFormsHost изменяются, чтобы вместить размещаемый элемент управления.
Изменение размеров в зависимости от содержимого
Элемент WindowsFormsHost обеспечивает то, что размер размещаемого элемента управления изменяется для правильного отображения его содержимого.
Для изменения размера в зависимости от содержимого
Скопируйте следующий код в элемент 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>
<!-- 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>
Нажмите клавишу F5 для построения и выполнения приложения. Размер двух новых кнопок корректно изменяется для отображения длинных строк текста и большого шрифта, а размер элементов WindowsFormsHost изменяется, чтобы вместить размещаемые элементы управления.
Использование абсолютного позиционирования
Абсолютное позиционирование можно использовать для размещения элемента WindowsFormsHost в любом месте в пользовательском интерфейсе.
Чтобы использовать абсолютное позиционирование
Скопируйте следующий код в элемент 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>
<!-- 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>
Нажмите клавишу F5 для построения и выполнения приложения. Элемент WindowsFormsHost размещается в 20 точках от верхнего края ячейки сетки и в 20 точках от левого края.
Задание размера явным образом
Можно указать размер элемента WindowsFormsHost с помощью Width и Height.
Чтобы явно указать размер
Скопируйте следующий код в элемент 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>
<!-- 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>
Нажмите клавишу F5 для построения и выполнения приложения. Размер элемента WindowsFormsHost устанавливается в 50 точек в ширину и в 70 точек в высоту — это меньше, чем параметры макета по умолчанию. Содержимое элемента управления Windows Forms упорядочивается соответствующим образом.
Установка свойств макета
Всегда следует задавать связанные с макетом свойства для размещаемого элемента управления с помощью свойств элемента WindowsFormsHost. При установке свойств макета непосредственно для размещаемого элемента управления результат не будет соответствовать ожидаемому.
Установка связанных с макетом свойств размещаемого элемента управления в 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="button1Click" Text="Click me" FlatStyle="Flat" BackColor="Green"/> </WindowsFormsHost> </Canvas>
<!-- Setting hosted control properties directly. --> <Canvas Grid.Row="0" Grid.Column="1"> <WindowsFormsHost Width="160" Height="50" Background="Yellow"> <wf:Button Name="button1" Click="button1Click" Text="Click me" FlatStyle="Flat" BackColor="Green"/> </WindowsFormsHost> </Canvas>
В обозревателе решений дважды щелкните на Window1.xaml.cs, чтобы открыть его в редакторе кода.
Скопируйте следующий код в определение класса Window1, сразу после конструктора Window1().
Private Sub button1Click(ByVal sender As Object, ByVal e As EventArgs) Dim b As System.Windows.Forms.Button = sender b.Top = 20 b.Left = 20 End Sub
private void button1Click(object sender, EventArgs e ) { System.Windows.Forms.Button b = sender as System.Windows.Forms.Button; b.Top = 20; b.Left = 20; }
Нажмите клавишу F5 для построения и выполнения приложения.
Нажмите кнопку Click Me. Обработчик событий button1Click задает свойства Top и Left размещаемого элемента управления. Это приводит к изменению положения размещаемого элемента управления в элементе WindowsFormsHost. Ведущий элемент занимает то же пространство на экране, но размещаемый элемент управления обрезается. Вместо этого размещаемый элемент управления должен всегда заполнять элемент WindowsFormsHost.
Описание ограничений z-порядка
Видимые элементы WindowsFormsHost всегда рисуются поверх других элементов WPF, и на них не влияет z-порядок.
Для просмотра ограничений z-порядка
В файле Window1.xaml скопируйте следующий код в элемент Grid после предыдущего примера кода.
<!-- Z-order demonstration. --> <Canvas Grid.Row="1" Grid.Column="1"> <Label Content="A WPF label" FontSize="24"/> <WindowsFormsHost Canvas.Top="20" Canvas.Left="20" Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> </Canvas>
<!-- Z-order demonstration. --> <Canvas Grid.Row="1" Grid.Column="1"> <Label Content="A WPF label" FontSize="24"/> <WindowsFormsHost Canvas.Top="20" Canvas.Left="20" Background="Yellow"> <wf:Button Text="Windows Forms control" FlatStyle="Flat"/> </WindowsFormsHost> </Canvas>
Нажмите клавишу F5 для построения и выполнения приложения. Элемент WindowsFormsHost рисуется через элемент метки.
Закрепление
Элемент WindowsFormsHost поддерживает закрепление WPF. Задайте вложенное свойство Dock, чтобы закрепить размещаемый элемент управления в элементе DockPanel.
Чтобы закрепить размещаемый элемент управления
Скопируйте следующий код в элемент 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>
<!-- 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>
Нажмите клавишу F5 для построения и выполнения приложения. Элемент WindowsFormsHost закрепляется по правой стороне элемента DockPanel.
Задание видимости
Элемент управления Windows Forms можно сделать невидимым или свернуть его, задав свойству Visibility элемента WindowsFormsHost. Если элемент управления невидим, он не отображается, но при этом занимает пространство разметки. Если элемент управления свернут, он не отображается и не занимает пространство разметки.
Чтобы задать видимость размещаемого элемента управления
Скопируйте следующий код в элемент Grid после предыдущего примера кода.
<!-- Setting Visibility to hidden and collapsed. --> <StackPanel Grid.Row="3" Grid.Column="1"> <Button Name="button2" Click="button2Click" 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="button3Click" Content="Click to collapse" Background="OrangeRed"/> </StackPanel>
<!-- Setting Visibility to hidden and collapsed. --> <StackPanel Grid.Row="3" Grid.Column="1"> <Button Name="button2" Click="button2Click" 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="button3Click" Content="Click to collapse" Background="OrangeRed"/> </StackPanel>
В обозревателе решений дважды щелкните на Window1.xaml.cs, чтобы открыть его в редакторе кода.
Скопируйте следующий код в определение класса Window1.
Private Sub button2Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Me.host1.Visibility = Windows.Visibility.Hidden End Sub Private Sub button3Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Me.host1.Visibility = Windows.Visibility.Collapsed End Sub
private void button2Click(object sender, EventArgs e) { this.host1.Visibility = Visibility.Hidden; } private void button3Click(object sender, EventArgs e) { this.host1.Visibility = Visibility.Collapsed; }
Нажмите клавишу F5 для построения и выполнения приложения.
Нажмите на кнопку Click to make invisible чтобы сделать элемент WindowsFormsHost невидимым.
Нажмите на кнопку Click to collapse кнопку, чтобы полностью скрыть элемент WindowsFormsHost в макете. Когда элемент управления Windows Forms свернут, соседние элементы переупорядочиваются, чтобы занять его место.
Размещение нерастягиваемых элементов управления
Некоторые элементы управления Windows Forms имеют фиксированный размер и не растягиваются для заполнения доступного места в макете. Например, элемент управления MonthCalendar отображает месяц в фиксированном пространстве.
Чтобы разместить нерастягиваемый элемент управления
Скопируйте следующий код в элемент 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>
<!-- 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>
Нажмите клавишу F5 для построения и выполнения приложения. Элемент WindowsFormsHost выравнивается по центру в строке сетки, но он не растягивается, чтобы заполнить доступное пространство. Если окно достаточно большое, можно увидеть два или более месяцев, отображаемых размещаемым элементом управления MonthCalendar, но они выравниваются по центру строки. Обработчик макета WPF выравнивает по центру элементы, размеры которых не меняются для заполнения доступного пространства.
Масштабирование
В отличие от элементов WPF, большинство элементов управления Windows Forms не являются непрерывно масштабируемыми. Элемент WindowsFormsHost масштабирует свой размещаемый элемент управления, когда это возможно.
Для масштабирования размещаемого элемента управления
Скопируйте следующий код в элемент 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>
<!-- 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>
Нажмите клавишу F5 для построения и выполнения приложения. Размещаемый элемент управления и окружающие его элементы масштабируются с коэффициентом, равным 0,5. Однако шрифт размещаемого элемента управления не масштабируется.
Поворот
В отличие от элементов WPF, элементы управления Windows Forms не поддерживают поворот. Элемент WindowsFormsHost не поворачивается вместе с другими элементами WPF при применении преобразования поворота. Любой угол поворота, отличный от 180 градусов, вызывает событие LayoutError.
Чтобы увидеть эффект от поворота в гибридном приложении
Скопируйте следующий код в элемент 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>
<!-- 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>
Нажмите клавишу F5 для построения и выполнения приложения. Размещаемый элемент управления не повернут, но его соседние элементы повернуты на угол в 180 градусов.
Задание полей и внутренних полей
Поля и внутренние поля в макете WPF похожи на свои аналоги в Windows Forms. Просто задайте свойства Padding и Margin элемента WindowsFormsHost.
Чтобы задать поля и внутренние поля размещаемого элемента управления
Скопируйте следующий код в элемент 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>
<!-- 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>
Нажмите клавишу F5 для построения и выполнения приложения. Параметры полей и внутренних полей будут применены к размещаемым элементам управления Windows Forms так же, как и в Windows Forms.
Использование динамических контейнеров макета
Windows Forms предоставляет два динамических контейнера макета, FlowLayoutPanel и TableLayoutPanel. Можно также использовать эти контейнеры в макетах WPF.
Чтобы использовать динамический контейнер макета
Скопируйте следующий код в элемент Grid после предыдущего примера кода.
<!-- Flow layout. --> <DockPanel Grid.Row="4" Grid.Column="2"> <WindowsFormsHost Name="flowLayoutHost" Background="Yellow"> <wf:FlowLayoutPanel/> </WindowsFormsHost> </DockPanel>
<!-- Flow layout. --> <DockPanel Grid.Row="4" Grid.Column="2"> <WindowsFormsHost Name="flowLayoutHost" Background="Yellow"> <wf:FlowLayoutPanel/> </WindowsFormsHost> </DockPanel>
В обозревателе решений дважды щелкните на Window1.xaml.cs, чтобы открыть его в редакторе кода.
Скопируйте следующий код в определение класса Window1.
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
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); } }
Добавьте вызов метода InitializeFlowLayoutPanel в конструктор.
Public Sub New() InitializeComponent() Me.InitializeFlowLayoutPanel() End Sub
public Window1() { InitializeComponent(); this.InitializeFlowLayoutPanel(); }
Нажмите клавишу F5 для построения и выполнения приложения. Элемент WindowsFormsHost заполняет DockPanel, а FlowLayoutPanel упорядочивает его дочерние элементы в направлении FlowDirection по умолчанию.
См. также
Задачи
Пример упорядочивания элементов управления Windows Forms в Windows Presentation Foundation
Основные понятия
Вопросы, связанные с макетом элемента WindowsFormsHost
Обзор: размещение элементов управления Windows Presentation Foundation в приложении Windows Forms