Пошаговое руководство. Размещение составного элемента управления Windows Forms в приложении WPF
Статья
Windows Presentation Foundation (WPF) предоставляет широкие возможности для создания приложений. Однако если у вас есть существенные инвестиции в код Windows Forms, это может быть более эффективным для повторного использования по крайней мере некоторых из этого кода в приложении WPF, а не для перезаписи его с нуля. Наиболее распространенным сценарием является наличие элементов управления Windows Forms. В некоторых случаях, возможно, у вас даже нет доступа к исходному коду для этих элементов управления. WPF предоставляет простую процедуру размещения таких элементов управления в приложении WPF. Например, можно использовать WPF для значительной части операций программирования при размещении специализированных элементов управления DataGridView.
В этом пошаговом руководстве создается приложение, в котором содержится составной элемент управления Windows Forms для поддержки ввода данных в WPF. Составной элемент управления упакован в библиотеку DLL. Эта общая процедура может быть расширена для более сложных приложений и элементов управления. Это пошаговое руководство почти идентично повторяет свойства и функциональные возможности, описанные в разделе Пошаговое руководство. Размещение составного элемента управления WPF в приложении Windows Forms. Основным отличием является то, что сценарий размещения выполняется в обратном порядке.
Пошаговое руководство состоит из двух разделов. В первом разделе кратко описывается реализация составного элемента управления Windows Forms. Во втором разделе подробно рассматриваются размещение составного элемента управления в приложении WPF, получение событий от него и доступ к некоторым свойствам элемента управления.
В данном пошаговом руководстве представлены следующие задачи.
Реализация составного элемента управления Windows Forms.
Для выполнения шагов, описанных в этом руководстве, вам понадобится Visual Studio.
Реализация составного элемента управления Windows Forms
Составной элемент управления Windows Forms, используемый в этом примере, представляет собой простую форму ввода данных. Эта форма принимает имя и адрес пользователя и затем использует пользовательское событие для возвращения сведений в основное приложение. На приведенном ниже рисунке показан отображаемый элемент управления.
На следующем рисунке показан составной элемент управления Windows Forms.
Создание проекта
Для запуска проекта выполните указанные ниже действия.
Запустите Visual Studio и откройте диалоговое окно Новый проект.
В категории Windows выберите шаблон Библиотека элементов управления Windows Forms.
Присвойте проекту имя MyControls.
В качестве расположения задайте папку верхнего уровня с понятным именем, например WpfHostingWindowsFormsControl. Позже ведущее приложение будет помещено в эту папку.
Нажмите кнопку ОК, чтобы создать проект. По умолчанию проект содержит один элемент управления с именем UserControl1.
В обозревателе решений переименуйте элемент управления UserControl1 в MyControl1.
Проект должен иметь ссылки на перечисленные ниже системные библиотеки DLL. Если какие-либо из этих библиотек DLL не включены по умолчанию, добавьте их в проект.
Система
System.Data
System.Drawing;
System.Windows.Forms.
System.Xml
Добавление элементов управления на форму
Чтобы добавить элементы управления в форму, выполните следующие действия.
Откройте MyControl1 в конструкторе.
Добавьте пять элементов управления Label и соответствующих элементов управления TextBox в масштабе и порядке, указанных на предыдущем рисунке, в форму. В этом примере элементы управления TextBox именуются следующим образом.
txtName
txtAddress
txtCity
txtState
txtZip
Добавьте два элемента управления Button с метками ОК и Отмена. В примере используются названия кнопок btnOK и btnCancel соответственно.
Реализация соответствующего кода
Откройте форму в представлении кода. Элемент управления возвращает собранные данные в основное приложение путем вызова пользовательского события OnButtonClick. Данные содержатся в объекте аргумента события. В следующем коде показано объявление события и делегата.
Добавьте в класс MyControl1 приведенный далее код.
Public Delegate Sub MyControlEventHandler(ByVal sender As Object, ByVal args As MyControlEventArgs)
Public Event OnButtonClick As MyControlEventHandler
Класс MyControlEventArgs содержит информацию, которая должна быть возвращена основному приложению.
Public Class MyControlEventArgs
Inherits EventArgs
Private _Name As String
Private _StreetAddress As String
Private _City As String
Private _State As String
Private _Zip As String
Private _IsOK As Boolean
Public Sub New(ByVal result As Boolean, ByVal name As String, ByVal address As String, ByVal city As String, ByVal state As String, ByVal zip As String)
_IsOK = result
_Name = name
_StreetAddress = address
_City = city
_State = state
_Zip = zip
End Sub
Public Property MyName() As String
Get
Return _Name
End Get
Set
_Name = value
End Set
End Property
Public Property MyStreetAddress() As String
Get
Return _StreetAddress
End Get
Set
_StreetAddress = value
End Set
End Property
Public Property MyCity() As String
Get
Return _City
End Get
Set
_City = value
End Set
End Property
Public Property MyState() As String
Get
Return _State
End Get
Set
_State = value
End Set
End Property
Public Property MyZip() As String
Get
Return _Zip
End Get
Set
_Zip = value
End Set
End Property
Public Property IsOK() As Boolean
Get
Return _IsOK
End Get
Set
_IsOK = value
End Set
End Property
End Class
При нажатии пользователем кнопки ОК или Отмена обработчики событий Click создают объект MyControlEventArgs, который содержит данные и вызывает событие OnButtonClick. Единственное различие между двумя обработчиками заключается в свойстве IsOK аргумента события. Это свойство позволяет основному приложению определить, какая кнопка была нажата. Ему присвоено значение true для кнопки ОК и значение false для кнопки Отмена. В следующем примере кода показаны два обработчика кнопок.
Добавьте в класс MyControl1 приведенный далее код.
Private Sub btnOK_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOK.Click
Dim retvals As New MyControlEventArgs(True, txtName.Text, txtAddress.Text, txtCity.Text, txtState.Text, txtZip.Text)
RaiseEvent OnButtonClick(Me, retvals)
End Sub
Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCancel.Click
Dim retvals As New MyControlEventArgs(False, txtName.Text, txtAddress.Text, txtCity.Text, txtState.Text, txtZip.Text)
RaiseEvent OnButtonClick(Me, retvals)
End Sub
Присвоение сборке строгого имени и построение сборки
Чтобы приложение WPF ссылалось на эту сборку, ей необходимо присвоить строгое имя. Для создания строгого имени создайте файл ключа с Sn.exe и добавьте его в свой проект.
Откройте командную строку Visual Studio. Для этого откройте меню Пуск, выберите Все программы/Microsoft Visual Studio 2010/Инструменты Visual Tools/Командная строка Visual Studio. Откроется окно консоли с настраиваемыми переменными среды.
В командной строке используйте команду cd, чтобы перейти к папке проекта.
Создайте файл ключа с именем MyControls.snk, выполнив следующую команду.
Консоль
Sn.exe -k MyControls.snk
Чтобы включить файл ключа в проект, щелкните правой кнопкой мыши имя проекта в обозревателе решений и выберите Свойства. В конструкторе проектов щелкните Подписи, установите флажок Подписать сборку, а затем перейдите к файлу ключа.
Постройте решение. Сборка создаст библиотеку DLL с именем MyControls.dll.
Реализация ведущего приложения WPF
Ведущее приложение WPF использует элемент управления WindowsFormsHost для размещения MyControl1. Приложение обрабатывает событие OnButtonClick для получения данных из элемента управления. Оно также содержит коллекцию переключателей, позволяющих менять некоторые свойства элемента управления из приложения WPF. Ниже показано готовое приложение.
На следующем рисунке показано приложение полностью, включая элемент управления, внедренный в приложение WPF.
Создание проекта
Для запуска проекта выполните указанные ниже действия.
Откройте Visual Studio и нажмите кнопку Новый проект.
В категории Window выберите шаблон Приложение WPF.
Присвойте проекту имя WpfHost.
В качестве расположения укажите ту же папку верхнего уровня, в которой содержится проект MyControls.
Нажмите кнопку ОК, чтобы создать проект.
Также необходимо добавить ссылки на библиотеку DLL, содержащую элемент управления MyControl1 и другие сборки.
Щелкните правой кнопкой мыши имя проекта в обозревателе решений и выберите команду Добавить ссылку.
Перейдите на вкладку Обзор и выберите папку, которая содержит файл MyControls.dll. В данном пошаговом руководстве это папка MyControls\bin\Debug.
Выберите файл MyControls.dll и нажмите кнопку ОК.
Добавьте ссылку на сборку WindowsFormsIntegration с именем WindowsFormsIntegration.dll.
Реализация базового макета
Пользовательский интерфейс ведущего приложения реализуется в файле MainWindow.xaml. Этот файл содержит расширяемую разметку языка разметки приложения (XAML), которая определяет макет и размещает элемент управления Windows Forms. Приложение состоит из трех областей:
Панель Свойства элемента управления, содержащая коллекцию переключателей, которые можно использовать для изменения различных свойств размещенного элемента управления.
Панель Данные из элемента управления, содержащая несколько элементов TextBlock, которые отображают данные, возвращенные из размещенного элемента управления.
Размещенный элемент.
Базовый макет показан в следующем XAML-коде. Разметка, необходимая для размещения MyControl1, пропущена в этом примере, однако этот вопрос рассматривается позже.
Замените XAML-код в файле MainWindow.xaml следующим. Если вы используете Visual Basic, измените класс на x:Class="MainWindow".
Первый элемент StackPanel содержит несколько наборов элементов управления RadioButton, которые позволяют вам модифицировать различные свойства по умолчанию размещенного элемента управления. За ним следует элемент WindowsFormsHost, в котором размещается MyControl1. И, наконец, элемент StackPanel содержит в себе несколько элементов TextBlock, которые служат для отображения данных, возвращаемых размещенным элементов управления. Порядок элементов и настройки атрибутов Dock и Height внедряют размещенный элемент в окно без промежутков и искажений.
Размещение элемента управления
В следующей отредактированной версии предыдущего XAML-кода особое внимание уделяется элементам, необходимым для размещения MyControl1.
Атрибут сопоставления пространства имен xmlns создает ссылку на пространство имен MyControls, которое содержит размещенный элемент управления. Это сопоставление позволяет представить MyControl1 в XAML в качестве <mcl:MyControl1>.
Два элемента в коде XAML обрабатывают размещение:
WindowsFormsHost представляет элемент WindowsFormsHost, позволяющий разместить элемент управления Windows Forms в приложении WPF.
mcl:MyControl1, представляющий MyControl1, добавляется в коллекцию дочерних элементов WindowsFormsHost. В результате этот элемент управления Windows Forms отрисовывается в составе окна WPF и из приложения можно взаимодействовать с этим элементом управления.
Реализация файла кода программной части
Файл кода программной части MainWindow.xaml.vb или MainWindow.xaml.cs содержит процедурный код, реализующий функциональные возможности пользовательского интерфейса, которые обсуждались в предыдущем разделе. Основные задачи
Присоединение обработчика событий к событию OnButtonClick объекта MyControl1.
Изменение различных свойств MyControl1 в зависимости от способа настройки коллекции переключателей.
Отображение данных, собранных с помощью элемента управления.
Инициализация приложения
Код инициализации содержится в обработчике событий для события Loaded окна и прикрепляет обработчик событий к событию OnButtonClick элемента управления.
В файле MainWindow.xaml.vb или MainWindow.xaml.cs добавьте в класс MainWindow следующий код.
Private app As Application
Private myWindow As Window
Private initFontWeight As FontWeight
Private initFontSize As [Double]
Private initFontStyle As FontStyle
Private initBackBrush As SolidColorBrush
Private initForeBrush As SolidColorBrush
Private initFontFamily As FontFamily
Private UIIsReady As Boolean = False
Private Sub Init(ByVal sender As Object, ByVal e As RoutedEventArgs)
app = System.Windows.Application.Current
myWindow = CType(app.MainWindow, Window)
myWindow.SizeToContent = SizeToContent.WidthAndHeight
wfh.TabIndex = 10
initFontSize = wfh.FontSize
initFontWeight = wfh.FontWeight
initFontFamily = wfh.FontFamily
initFontStyle = wfh.FontStyle
initBackBrush = CType(wfh.Background, SolidColorBrush)
initForeBrush = CType(wfh.Foreground, SolidColorBrush)
Dim mc As MyControl1 = wfh.Child
AddHandler mc.OnButtonClick, AddressOf Pane1_OnButtonClick
UIIsReady = True
End Sub
Так как код XAML, обсужденный ранее, добавляет MyControl1 в коллекцию дочерних элементов WindowsFormsHost, можно привести член Child элемента WindowsFormsHost, чтобы получить ссылку на MyControl1. Затем можно использовать эту ссылку для присоединения обработчика событий к OnButtonClick.
Помимо предоставления ссылки на элемент управления, WindowsFormsHost предоставляет ряд свойств элемента управления, которыми можно управлять из приложения. Код инициализации назначает эти значения закрытым глобальным переменным для последующего использования в приложении.
Это позволяет легко осуществлять доступ к типам в библиотеке DLL MyControls, добавлять инструкцию Imports или using в начало файла.
Imports MyControls
C#
using MyControls;
Обработка события OnButtonClick
MyControl1 вызывает событие OnButtonClick при нажатии любой из кнопок элемента управления.
Добавьте в класс MainWindow приведенный далее код.
'Handle button clicks on the Windows Form control
Private Sub Pane1_OnButtonClick(ByVal sender As Object, ByVal args As MyControlEventArgs)
txtName.Inlines.Clear()
txtAddress.Inlines.Clear()
txtCity.Inlines.Clear()
txtState.Inlines.Clear()
txtZip.Inlines.Clear()
If args.IsOK Then
txtName.Inlines.Add(" " + args.MyName)
txtAddress.Inlines.Add(" " + args.MyStreetAddress)
txtCity.Inlines.Add(" " + args.MyCity)
txtState.Inlines.Add(" " + args.MyState)
txtZip.Inlines.Add(" " + args.MyZip)
End If
End Sub
Данные в текстовых полях упакованы в объект MyControlEventArgs. Если пользователь нажимает кнопку ОК, обработчик событий извлекает данные и отображает их на панели ниже MyControl1.
Изменение свойств элемента управления
Элемент WindowsFormsHost предоставляет несколько свойств по умолчанию для размещенных элементов. В результате можно изменить внешний вид элемента управления, чтобы он более полно соответствовал стилю приложения. Наборы переключателей на левой панели позволяют пользователю изменять некоторые свойства цвета и шрифта. Каждый набор кнопок имеет обработчик для события Click, которое обнаруживает, какой переключатель нажал пользователь, и меняет соответствующее свойство элемента управления.
Добавьте в класс MainWindow приведенный далее код.
Private Sub BackColorChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnBackGreen) Then
wfh.Background = New SolidColorBrush(Colors.LightGreen)
ElseIf sender.Equals(rdbtnBackSalmon) Then
wfh.Background = New SolidColorBrush(Colors.LightSalmon)
ElseIf UIIsReady = True Then
wfh.Background = initBackBrush
End If
End Sub
Private Sub ForeColorChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnForeRed) Then
wfh.Foreground = New SolidColorBrush(Colors.Red)
ElseIf sender.Equals(rdbtnForeYellow) Then
wfh.Foreground = New SolidColorBrush(Colors.Yellow)
ElseIf UIIsReady = True Then
wfh.Foreground = initForeBrush
End If
End Sub
Private Sub FontChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnTimes) Then
wfh.FontFamily = New FontFamily("Times New Roman")
ElseIf sender.Equals(rdbtnWingdings) Then
wfh.FontFamily = New FontFamily("Wingdings")
ElseIf UIIsReady = True Then
wfh.FontFamily = initFontFamily
End If
End Sub
Private Sub FontSizeChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnTen) Then
wfh.FontSize = 10
ElseIf sender.Equals(rdbtnTwelve) Then
wfh.FontSize = 12
ElseIf UIIsReady = True Then
wfh.FontSize = initFontSize
End If
End Sub
Private Sub StyleChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnItalic) Then
wfh.FontStyle = FontStyles.Italic
ElseIf UIIsReady = True Then
wfh.FontStyle = initFontStyle
End If
End Sub
Private Sub WeightChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnBold) Then
wfh.FontWeight = FontWeights.Bold
ElseIf UIIsReady = True Then
wfh.FontWeight = initFontWeight
End If
End Sub
Выполните сборку приложения и запустите его. Добавьте какой-нибудь текст в составной элемент управления Windows Forms и нажмите кнопку ОК. Этот текст появится в метках. Щелкайте различные переключатели, чтобы увидеть соответствующий эффект в элементе управления.
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Отзыв о .NET Desktop feedback
.NET Desktop feedback — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв:
Присоединитесь к серии встреч для создания масштабируемых решений искусственного интеллекта на основе реальных вариантов использования с другими разработчиками и экспертами.
Создайте пользовательский интерфейс с привязкой данных. Пользовательский интерфейс автоматически обновляется на основе последних данных, а данные обновляются в ответ на изменения в пользовательском интерфейсе.
Учебник. Размещение элементов управления Windows Forms в платформе Windows Presentation Foundation, где уже предоставлены множество элементов управления с широким набором функций.
Узнайте, как использовать свойство PropertyMap для сопоставления свойств Windows Presentation Foundation в размещенном элементе управления Windows Forms.