Пошаговое руководство. Размещение составного элемента управления WPF в форме Windows Forms
Клиент Windows Presentation Foundation (WPF) предоставляет среду с широкими возможностями для создания приложений. Однако если имеющийся код Windows Forms содержит важные элементы, более эффективным может быть расширение существующего приложения Windows Forms с помощью клиента WPF, а не переписывание кода "с нуля". Один из распространенных сценариев состоит в необходимости внедрения одного или нескольких элементов управления, реализованных с помощью WPF, в приложение Windows Forms. Дополнительные сведения о настройке элементов управления WPF см. в разделе Настройка элементов управления.
В данном пошаговом руководстве создается приложение, в котором содержится составной элемент управления WPF для поддержки ввода данных в Windows Forms. Составной элемент управления упакован в библиотеку DLL. Эта общая процедура может быть расширена для более сложных приложений и элементов управления. Это пошаговое руководство почти идентично повторяет свойства и функциональные возможности, описанные в разделе Пошаговое руководство. Размещение составного элемента управления Windows Forms в приложении WPF. Основным различием является то, что скрипт размещения выполняется в обратном порядке.
Данное пошаговое руководство разделено на два раздела. В первом разделе кратко описывается реализация составного элемента управления WPF. Во втором разделе подробно рассматривается размещение составного элемента управления в приложении Windows Forms, получение событий из элемента управления и доступ к некоторым свойствам элемента управления.
В этом пошаговом руководстве демонстрируется выполнение следующих задач.
Реализация составного элемента управления WPF
Реализация ведущего приложения Windows Forms.
Полный пример кода для задач, приведенных в этом руководстве, см. в разделе Пример размещения составного элемента управления Windows Forms в приложении WPF.
Предварительные требования
Ниже приведены компоненты, необходимые для выполнения данного пошагового руководства.
- Visual Studio 2010.
Реализация составного элемента управления WPF
Составной элемент управления WPF, используемый в этом примере, представляет собой простую форму ввода данных, содержащую поля для имени пользователя и его адреса. Когда пользователь нажимает одну из двух кнопок, чтобы указать, что задача завершена, элемент управления создает пользовательское событие для возвращения сведений в ведущее приложение. На следующем рисунке показан отображаемый элемент управления.
Составной элемент управления WPF
Создание проекта
Для запуска проекта выполните следующие действия.
Запустите среду Microsoft Visual Studio и откройте диалоговое окно Новый проект.
В Visual C# и категории Windows выберите шаблон Библиотека пользовательских элементов управления WPF.
Присвойте проекту имя MyControls.
В качестве расположения задайте папку верхнего уровня с понятным именем, например WindowsFormsHostingWpfControl. Позже ведущее приложение будет помещено в эту папку.
Нажмите кнопку ОК, чтобы создать проект. По умолчанию проект содержит одну страницу с именем UserControl1.
В обозревателе решений переименуйте элемент управления UserControl1 в MyControl1.
Проект должен иметь ссылки на следующие системные библиотеки DLL. Если какие-либо из этих библиотек DLL не включены по умолчанию, добавьте их в проект.
PresentationCore
PresentationFramework
Система
WindowsBase
Создание пользовательского интерфейса
user interface (UI) для составного элемента управления реализуется с помощью языка Extensible Application Markup Language (XAML). UI составного элемента управления состоит из пяти элементов TextBox. Каждый элемент TextBox имеет связанный элемент TextBlock, служащий в качестве метки. В нижней части элемента управления имеются два элемента Button — OK и Cancel. При нажатии любой кнопки элемент управления создает пользовательское событие для возвращения сведений в ведущее приложение.
Базовый макет
В элементе Grid содержатся различные элементы UI. Объект Grid используется для размещения содержимого составного элемента управления практически так же, как элемент Table в HTML. В WPF также имеется элемент Table, но объект Grid проще использовать; кроме того, с его помощью лучше выполняются простые задачи компоновки.
В следующем коде XAML показан базовый макет. Этот код XAML определяет общую структуру элемента управления, указывая число столбцов и строк в элементе Grid.
В файле MyControl1.xaml замените имеющийся код XAML следующим кодом.
<Grid xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyControls.MyControl1"
Background="#DCDCDC"
Width="375"
Height="250"
Name="rootElement"
Loaded="Init">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
...
</Grid>
Добавление в сетку элементов TextBlock и TextBox
Элемент UI помещается в сетке посредством задания атрибутам RowProperty и ColumnProperty элемента соответствующего номера строки и столбца. Следует помнить, что нумерация строк и столбцов ведется от нуля. Можно создать общий элемент для нескольких столбцов, задав атрибут ColumnSpanProperty. Дополнительные сведения об элементах Grid см. в разделе Практическое руководство. Создание элемента сетки.
В следующем коде XAML показаны элементы TextBox и TextBlock составного элемента управления и их атрибуты RowProperty и ColumnProperty, с помощью которых задается правильное расположение элементов в сетке.
В файле MyControl1.xaml добавьте следующий код XAML в элементе Grid.
<TextBlock Grid.Column="0"
Grid.Row="0"
Grid.ColumnSpan="4"
Margin="10,5,10,0"
HorizontalAlignment="Center"
Style="{StaticResource titleText}">Simple WPF Control</TextBlock>
<TextBlock Grid.Column="0"
Grid.Row="1"
Style="{StaticResource inlineText}"
Name="nameLabel">Name</TextBlock>
<TextBox Grid.Column="1"
Grid.Row="1"
Grid.ColumnSpan="3"
Name="txtName"/>
<TextBlock Grid.Column="0"
Grid.Row="2"
Style="{StaticResource inlineText}"
Name="addressLabel">Street Address</TextBlock>
<TextBox Grid.Column="1"
Grid.Row="2"
Grid.ColumnSpan="3"
Name="txtAddress"/>
<TextBlock Grid.Column="0"
Grid.Row="3"
Style="{StaticResource inlineText}"
Name="cityLabel">City</TextBlock>
<TextBox Grid.Column="1"
Grid.Row="3"
Width="100"
Name="txtCity"/>
<TextBlock Grid.Column="2"
Grid.Row="3"
Style="{StaticResource inlineText}"
Name="stateLabel">State</TextBlock>
<TextBox Grid.Column="3"
Grid.Row="3"
Width="50"
Name="txtState"/>
<TextBlock Grid.Column="0"
Grid.Row="4"
Style="{StaticResource inlineText}"
Name="zipLabel">Zip</TextBlock>
<TextBox Grid.Column="1"
Grid.Row="4"
Width="100"
Name="txtZip"/>
Создание стилей элементов пользовательского интерфейса
Многие элементы в форме для ввода данных имеют одинаковый внешний вид; это означает, что они имеют одинаковые параметры нескольких свойств. Вместо того чтобы устанавливать атрибуты отдельно для каждого элемента, в предыдущем коде XAML используются элементы Style для определения стандартных параметров свойств классов элементов. Такой подход упрощает элемент управления и позволяет изменять внешний вид нескольких элементов посредством одного атрибута стиля.
Элементы Style содержатся в свойстве Resources элемента Grid, поэтому они могут использоваться всеми элементами в элементе управления. Если стиль поименован, он применяется к элементу посредством добавления набора элементов Style к стилю с заданным именем. Непоименованные стили становятся стилями по умолчанию для элемента. Дополнительные сведения о стилях WPF см. в разделе Стилизация и использование шаблонов.
В следующем коде XAML показаны элементы Style для составного элемента управления. Чтобы увидеть, как стили применяются к элементам, см. предыдущий код XAML. Например, последний элемент TextBlock имеет стиль inlineText, а в последнем элементе TextBox используется стиль по умолчанию.
В файле MyControl1.xaml добавьте следующий код XAML сразу после начального элемента Grid.
<Grid.Resources>
<Style x:Key="inlineText" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="10,5,10,0"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="12"/>
</Style>
<Style x:Key="titleText" TargetType="{x:Type TextBlock}">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Margin" Value="10,5,10,0"/>
</Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Margin" Value="10,5,10,0"/>
<Setter Property="Width" Value="60"/>
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="10,5,10,0"/>
</Style>
</Grid.Resources>
Добавление кнопок "ОК" и "Отмена"
Завершающими элементами составного элемента управления являются элементы Button OK и Cancel, которые занимают первые два столбца последней строки элемента Grid. Эти элементы используют общий обработчик событий ButtonClicked и стиль по умолчанию Button, определенный в предыдущем коде XAML.
В файле MyControl1.xaml добавьте следующий код XAML после последнего элемента TextBox. Часть XAML составного элемента управления завершена.
<Button Grid.Row="5"
Grid.Column="0"
Name="btnOK"
Click="ButtonClicked">OK</Button>
<Button Grid.Row="5"
Grid.Column="1"
Name="btnCancel"
Click="ButtonClicked">Cancel</Button>
Реализация файла кода программной части
Файл кода программной части MyControl1.xaml.cs реализует три важные задачи.
Обрабатывает событие, когда пользователь нажимает одну из кнопок.
Извлекает данные из элементов TextBox и пакует их в объект аргумента пользовательского события.
Вызывает пользовательское событие OnButtonClick, которое уведомляет узел, что пользователь завершил работу, и возвращает данные на узел.
Элемент управления также предоставляет ряд свойств цвета и шрифтов, которые позволяют изменять внешний вид. В отличие от классаWindowsFormsHost, который используется для размещения элемента управления Windows Forms, класс ElementHost предоставляет только свойство Background элемента управления. Чтобы обеспечить сходство между этим примером кода и примером, который обсуждается в разделе Пошаговое руководство. Размещение составного элемента управления Windows Forms в приложении WPF, элемент управления непосредственно предоставляет остальные свойства.
Базовая структура файла кода программной части
Файл кода программной части содержит одно пространство имен MyControls, которое состоит из двух классов — MyControl1 и MyControlEventArgs.
namespace MyControls
{
public partial class MyControl1 : Grid
{
//...
}
public class MyControlEventArgs : EventArgs
{
//...
}
}
Первый класс, MyControl1, — это разделяемый класс, содержащий код, который реализует функциональные возможности UI, определенного в файле MyControl1.xaml. При синтаксическом анализе файла MyControl1.xaml код XAML преобразуется в тот же разделяемый класс, и два разделяемых класса объединяются для формирования скомпилированного элемента управления. По этой причине имя класса в файле кода программной части должно совпадать с именем класса, назначенным в файле MyControl1.xaml, и оно должно наследоваться от корневого элемента элемента управления. Второй класс MyControlEventArgs является классом аргументов события, который используется для возвращения данных на узел.
Откройте файл MyControl1.xaml.cs. Измените существующее объявление класса, чтобы он имел следующее имя и наследовался от элемента Grid.
public partial class MyControl1 : Grid
Инициализация элемента управления
Следующий код реализует несколько основных задач.
Объявляет частное событие OnButtonClick и его связанный делегат MyControlEventHandler.
Создает несколько частных глобальных переменных, хранящих данные пользователя. Эти данные предоставляются через соответствующие свойства.
Реализует обработчик Init для события Loaded элемента управления. Этот обработчик инициализирует глобальные переменные путем назначения их значений, определенных в файле MyControl1.xaml. Для этого он использует свойство Name, назначенное типичному элементу TextBlock nameLabel, для доступа к параметрам свойств этого элемента.
Удалите существующий конструктор и добавьте следующий код в класс MyControl1.
public delegate void MyControlEventHandler(object sender, MyControlEventArgs args);
public event MyControlEventHandler OnButtonClick;
private FontWeight _fontWeight;
private double _fontSize;
private FontFamily _fontFamily;
private FontStyle _fontStyle;
private SolidColorBrush _foreground;
private SolidColorBrush _background;
private void Init(object sender, EventArgs e)
{
//They all have the same style, so use nameLabel to set initial values.
_fontWeight = nameLabel.FontWeight;
_fontSize = nameLabel.FontSize;
_fontFamily = nameLabel.FontFamily;
_fontStyle = nameLabel.FontStyle;
_foreground = (SolidColorBrush)nameLabel.Foreground;
_background = (SolidColorBrush)rootElement.Background;
}
Обработка событий нажатия кнопки
Пользователь указывает, что задача ввода данных завершена, нажав кнопку OK или Cancel. Обе кнопки используют тот же обработчик событий Click — ButtonClicked. Обе кнопки имеют имя btnOK или btnCancel, которое позволяет обработчику определить, какая кнопка была нажата, путем проверки значения аргумента sender. Обработчик выполняет следующие действия.
Создает объект MyControlEventArgs, содержащий данные из элементов TextBox.
Если пользователь нажимает кнопку Отмена, для свойства IsOK объекта MyControlEventArgs задает значение false.
Вызывает событие OnButtonClick, чтобы указать узлу, что пользователь завершил работу, и передает обратно собранные данные.
Добавьте следующий код в класс MyControl1 после метода Init.
private void ButtonClicked(object sender, RoutedEventArgs e)
{
MyControlEventArgs retvals = new MyControlEventArgs(true,
txtName.Text,
txtAddress.Text,
txtCity.Text,
txtState.Text,
txtZip.Text);
if (sender == btnCancel)
{
retvals.IsOK = false;
}
if (OnButtonClick != null)
OnButtonClick(this, retvals);
}
Создание свойств
Оставшаяся часть класса просто предоставляет свойства, которые соответствуют описанным выше глобальным переменным. При изменении свойства метод доступа set изменяет внешний вид элемента управления путем изменения соответствующих свойств элемента и обновления базовых глобальных переменных.
Добавьте следующий код к классу MyControl1.
public FontWeight MyControl_FontWeight
{
get { return _fontWeight; }
set
{
_fontWeight = value;
nameLabel.FontWeight = value;
addressLabel.FontWeight = value;
cityLabel.FontWeight = value;
stateLabel.FontWeight = value;
zipLabel.FontWeight = value;
}
}
public double MyControl_FontSize
{
get { return _fontSize; }
set
{
_fontSize = value;
nameLabel.FontSize = value;
addressLabel.FontSize = value;
cityLabel.FontSize = value;
stateLabel.FontSize = value;
zipLabel.FontSize = value;
}
}
public FontStyle MyControl_FontStyle
{
get { return _fontStyle; }
set
{
_fontStyle = value;
nameLabel.FontStyle = value;
addressLabel.FontStyle = value;
cityLabel.FontStyle = value;
stateLabel.FontStyle = value;
zipLabel.FontStyle = value;
}
}
public FontFamily MyControl_FontFamily
{
get { return _fontFamily; }
set
{
_fontFamily = value;
nameLabel.FontFamily = value;
addressLabel.FontFamily = value;
cityLabel.FontFamily = value;
stateLabel.FontFamily = value;
zipLabel.FontFamily = value;
}
}
public SolidColorBrush MyControl_Background
{
get { return _background; }
set
{
_background = value;
rootElement.Background = value;
}
}
public SolidColorBrush MyControl_Foreground
{
get { return _foreground; }
set
{
_foreground = value;
nameLabel.Foreground = value;
addressLabel.Foreground = value;
cityLabel.Foreground = value;
stateLabel.Foreground = value;
zipLabel.Foreground = value;
}
}
Отправка данных обратно на узел
Завершающим компонентом в файле является класс MyControlEventArgs, который используется для отправки собранных данных обратно на узел.
Добавьте следующий код к пространству имен MyControls. Реализация является простой и далее не рассматривается.
public class MyControlEventArgs : EventArgs
{
private string _Name;
private string _StreetAddress;
private string _City;
private string _State;
private string _Zip;
private bool _IsOK;
public MyControlEventArgs(bool result,
string name,
string address,
string city,
string state,
string zip)
{
_IsOK = result;
_Name = name;
_StreetAddress = address;
_City = city;
_State = state;
_Zip = zip;
}
public string MyName
{
get { return _Name; }
set { _Name = value; }
}
public string MyStreetAddress
{
get { return _StreetAddress; }
set { _StreetAddress = value; }
}
public string MyCity
{
get { return _City; }
set { _City = value; }
}
public string MyState
{
get { return _State; }
set { _State = value; }
}
public string MyZip
{
get { return _Zip; }
set { _Zip = value; }
}
public bool IsOK
{
get { return _IsOK; }
set { _IsOK = value; }
}
}
Выполните построение решения. Построение создаст DLL с именем MyControls.dll.
Реализация ведущего приложения Windows Forms
Для размещения составного элемента управления WPF в ведущем приложении Windows Forms используется объект ElementHost. Приложение обрабатывает событие OnButtonClick для получения данных из составного элемента управления. Приложение также содержит набор переключателей, которые можно использовать для изменения внешнего вида элемента управления. На следующем рисунке показано приложение.
Составной элемент управления WPF в приложении Windows Forms
Создание проекта
Для запуска проекта выполните следующие действия.
Запустите среду Visual Studio и откройте диалоговое окно Новый проект.
В Visual C# и категории Windows выберите шаблон Приложение Windows Forms.
Присвойте проекту имя WFHost.
В качестве расположение укажите ту же папку верхнего уровня, в которой содержится проект MyControls.
Нажмите кнопку ОК, чтобы создать проект.
Также необходимо добавить ссылки на библиотеку DLL, содержащую элемент управления MyControl1 и другие сборки.
Щелкните правой кнопкой мыши имя проекта в обозревателе решений и выберите команду Добавить ссылку.
Перейдите на вкладку Обзор и укажите папку, которая содержит файл MyControls.dll. В данном пошаговом руководстве это папка MyControls\bin\Debug.
Выберите файл MyControls.dll и нажмите кнопку ОК.
Добавьте ссылки на следующие сборки:
PresentationCore
PresentationFramework
System.Xaml
WindowsBase
WindowsFormsIntegration
Реализация пользовательского интерфейса для приложения
Пользовательский интерфейс приложения Windows Form содержит несколько элементов управления для взаимодействия с составным элементом управления WPF.
Откройте приложение Form1 в конструкторе Windows Form.
Увеличьте форму, чтобы разместить элементы управления.
Добавьте элемент управления System.Windows.Forms.Panel в правый верхний угол формы для размещения составного элемента управления WPF.
Добавьте в форму следующие элементы управления System.Windows.Forms.GroupBox.
Имя
Текст
groupBox1
Цвет фона
groupBox2
Цвет шрифта
groupBox3
Font Size
groupBox4
Семейство шрифтов
groupBox5
Стиль шрифта
groupBox6
Насыщенность шрифта
groupBox7
Данные из элемента управления
Добавьте в элементы управления System.Windows.Forms.GroupBox следующие элементы управления System.Windows.Forms.RadioButton.
GroupBox
Имя
Текст
groupBox1
radioBackgroundOriginal
До преобразования
groupBox1
radioBackgroundLightGreen
LightGreen
groupBox1
radioBackgroundLightSalmon
LightSalmon
groupBox2
radioForegroundOriginal
До преобразования
groupBox2
radioForegroundRed
Красный
groupBox2
radioForegroundYellow
Желтый
groupBox3
radioSizeOriginal
До преобразования
groupBox3
radioSizeTen
10
groupBox3
radioSizeTwelve
12
groupBox4
radioFamilyOriginal
До преобразования
groupBox4
radioFamilyTimes
Times New Roman
groupBox4
radioFamilyWingDings
WingDings
groupBox5
radioStyleOriginal
Обычный
groupBox5
radioStyleItalic
Курсив
groupBox6
radioWeightOriginal
До преобразования
groupBox6
radioWeightBold
Полужирный
Добавьте в последний элемент управления System.Windows.Forms.GroupBox следующие элементы управления System.Windows.Forms.Label. Эти элементы управления отображают данные, возвращенные составным элементом управления WPF.
GroupBox
Имя
Текст
groupBox7
lblName
Имя:
groupBox7
lblAddress
Street Address:
groupBox7
lblCity
City:
groupBox7
lblState
State:
groupBox7
lblZip
Zip:
Инициализация формы
Код размещения обычно реализуется в обработчике событий Load формы. В следующем коде показан обработчик событий Load, обработчик событий Loaded составного элемента управления WPF и объявления нескольких глобальных переменных, которые будут использованы позже.
В конструкторе Windows Forms дважды щелкните форму, чтобы создать обработчик событий Load. В начале файла Form1.cs добавьте следующие операторы using.
using System;
using System.Windows;
using System.Windows.Navigation;
using System.Windows.Controls;
using System.Windows.Media;
namespace MyControls
{
public partial class MyControl1 : Grid
{
public delegate void MyControlEventHandler(object sender, MyControlEventArgs args);
public event MyControlEventHandler OnButtonClick;
private FontWeight _fontWeight;
private double _fontSize;
private FontFamily _fontFamily;
private FontStyle _fontStyle;
private SolidColorBrush _foreground;
private SolidColorBrush _background;
private void Init(object sender, EventArgs e)
{
//They all have the same style, so use nameLabel to set initial values.
_fontWeight = nameLabel.FontWeight;
_fontSize = nameLabel.FontSize;
_fontFamily = nameLabel.FontFamily;
_fontStyle = nameLabel.FontStyle;
_foreground = (SolidColorBrush)nameLabel.Foreground;
_background = (SolidColorBrush)rootElement.Background;
}
private void ButtonClicked(object sender, RoutedEventArgs e)
{
MyControlEventArgs retvals = new MyControlEventArgs(true,
txtName.Text,
txtAddress.Text,
txtCity.Text,
txtState.Text,
txtZip.Text);
if (sender == btnCancel)
{
retvals.IsOK = false;
}
if (OnButtonClick != null)
OnButtonClick(this, retvals);
}
public FontWeight MyControl_FontWeight
{
get { return _fontWeight; }
set
{
_fontWeight = value;
nameLabel.FontWeight = value;
addressLabel.FontWeight = value;
cityLabel.FontWeight = value;
stateLabel.FontWeight = value;
zipLabel.FontWeight = value;
}
}
public double MyControl_FontSize
{
get { return _fontSize; }
set
{
_fontSize = value;
nameLabel.FontSize = value;
addressLabel.FontSize = value;
cityLabel.FontSize = value;
stateLabel.FontSize = value;
zipLabel.FontSize = value;
}
}
public FontStyle MyControl_FontStyle
{
get { return _fontStyle; }
set
{
_fontStyle = value;
nameLabel.FontStyle = value;
addressLabel.FontStyle = value;
cityLabel.FontStyle = value;
stateLabel.FontStyle = value;
zipLabel.FontStyle = value;
}
}
public FontFamily MyControl_FontFamily
{
get { return _fontFamily; }
set
{
_fontFamily = value;
nameLabel.FontFamily = value;
addressLabel.FontFamily = value;
cityLabel.FontFamily = value;
stateLabel.FontFamily = value;
zipLabel.FontFamily = value;
}
}
public SolidColorBrush MyControl_Background
{
get { return _background; }
set
{
_background = value;
rootElement.Background = value;
}
}
public SolidColorBrush MyControl_Foreground
{
get { return _foreground; }
set
{
_foreground = value;
nameLabel.Foreground = value;
addressLabel.Foreground = value;
cityLabel.Foreground = value;
stateLabel.Foreground = value;
zipLabel.Foreground = value;
}
}
}
public class MyControlEventArgs : EventArgs
{
private string _Name;
private string _StreetAddress;
private string _City;
private string _State;
private string _Zip;
private bool _IsOK;
public MyControlEventArgs(bool result,
string name,
string address,
string city,
string state,
string zip)
{
_IsOK = result;
_Name = name;
_StreetAddress = address;
_City = city;
_State = state;
_Zip = zip;
}
public string MyName
{
get { return _Name; }
set { _Name = value; }
}
public string MyStreetAddress
{
get { return _StreetAddress; }
set { _StreetAddress = value; }
}
public string MyCity
{
get { return _City; }
set { _City = value; }
}
public string MyState
{
get { return _State; }
set { _State = value; }
}
public string MyZip
{
get { return _Zip; }
set { _Zip = value; }
}
public bool IsOK
{
get { return _IsOK; }
set { _IsOK = value; }
}
}
}
using System.Windows;
using System.Windows.Forms.Integration;
using System.Windows.Media;
Замените содержимое существующего класса Form1 следующим кодом.
private ElementHost ctrlHost;
private MyControls.MyControl1 wpfAddressCtrl;
System.Windows.FontWeight initFontWeight;
double initFontSize;
System.Windows.FontStyle initFontStyle;
System.Windows.Media.SolidColorBrush initBackBrush;
System.Windows.Media.SolidColorBrush initForeBrush;
System.Windows.Media.FontFamily initFontFamily;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
ctrlHost = new ElementHost();
ctrlHost.Dock = DockStyle.Fill;
panel1.Controls.Add(ctrlHost);
wpfAddressCtrl = new MyControls.MyControl1();
wpfAddressCtrl.InitializeComponent();
ctrlHost.Child = wpfAddressCtrl;
wpfAddressCtrl.OnButtonClick +=
new MyControls.MyControl1.MyControlEventHandler(
avAddressCtrl_OnButtonClick);
wpfAddressCtrl.Loaded += new RoutedEventHandler(
avAddressCtrl_Loaded);
}
void avAddressCtrl_Loaded(object sender, EventArgs e)
{
initBackBrush = (SolidColorBrush)wpfAddressCtrl.MyControl_Background;
initForeBrush = wpfAddressCtrl.MyControl_Foreground;
initFontFamily = wpfAddressCtrl.MyControl_FontFamily;
initFontSize = wpfAddressCtrl.MyControl_FontSize;
initFontWeight = wpfAddressCtrl.MyControl_FontWeight;
initFontStyle = wpfAddressCtrl.MyControl_FontStyle;
}
Метод Form1_Load в предыдущем коде показывает общую процедуру размещения элемента управления WPF.
Создайте новый объект ElementHost.
Присвойте свойству Dock элемента управления значение DockStyle.Fill.
Добавьте элемент управления ElementHost к коллекции Controls элементов управления Panel.
Создайте экземпляр элемента управления WPF.
Разместите составной элемент управления в форме путем назначения элемента управления свойству Child элемента управления ElementHost.
Остальные две строки в методе Form1_Load присоединяют обработчики к двум событиям элемента управления:
OnButtonClick — пользовательское событие, создаваемое составным элементом управления при нажатии кнопки OK или Cancel. Обработайте событие для получения ответа пользователя и сбора всех введенных им данных.
Loaded — стандартное событие, которое вызывается элементом управления WPF, когда он полностью загружен. Это событие используется здесь потому, что для примера необходима инициализация нескольких глобальных переменных свойствами элемента управления. Во время события Load формы элемент управления не полностью загружен, и для этих переменных по-прежнему задается значение null. Прежде чем получить доступ к этим свойствам, необходимо дождаться события Loaded элемента управления.
Обработчик событий Loaded показан в предыдущем коде. Обработчик OnButtonClick рассматривается в следующем разделе.
Обработка события OnButtonClick
Событие OnButtonClick происходит, когда пользователь нажимает кнопку ОК или Отмена.
Обработчик событий проверяет поле IsOK аргумента события, чтобы определить, какая кнопка была нажата. Переменные lbldata соответствуют элементам управления Label, которые были описаны выше. Если пользователь нажимает кнопку ОК, данные из элементов управления TextBox элемента управления назначаются соответствующему элементу управления Label. Если пользователь нажимает кнопку Cancel, для свойств Text устанавливаются строки по умолчанию.
Добавьте следующий код обработчика событий нажатия кнопки в класс Form1.
void avAddressCtrl_OnButtonClick(
object sender,
MyControls.MyControl1.MyControlEventArgs args)
{
if (args.IsOK)
{
lblAddress.Text = "Street Address: " + args.MyStreetAddress;
lblCity.Text = "City: " + args.MyCity;
lblName.Text = "Name: " + args.MyName;
lblState.Text = "State: " + args.MyState;
lblZip.Text = "Zip: " + args.MyZip;
}
else
{
lblAddress.Text = "Street Address: ";
lblCity.Text = "City: ";
lblName.Text = "Name: ";
lblState.Text = "State: ";
lblZip.Text = "Zip: ";
}
}
Постройте и запустите приложение. Добавьте произвольный текст в составной элемент управления WPF и нажмите кнопку OK. Этот текст появится в подписях. На данном этапе код для обработки переключателей еще не добавлен.
Изменение внешнего вида элемента управления
Элементы управления RadioButton формы позволяют пользователю изменять цвет шрифта и фона составного элемента управления WPF, а также ряд свойств шрифта. Цвет фона предоставляется объектом ElementHost. Остальные свойства предоставляются как настраиваемые свойства элемента управления.
Дважды щелкните каждый элемент управления RadioButton в форме, чтобы создать обработчики событий CheckedChanged. Замените обработчики событий CheckedChanged следующим кодом.
private void radioBackgroundOriginal_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_Background = initBackBrush;
}
private void radioBackgroundLightGreen_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_Background = new SolidColorBrush(Colors.LightGreen);
}
private void radioBackgroundLightSalmon_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_Background = new SolidColorBrush(Colors.LightSalmon);
}
private void radioForegroundOriginal_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_Foreground = initForeBrush;
}
private void radioForegroundRed_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_Foreground = new System.Windows.Media.SolidColorBrush(Colors.Red);
}
private void radioForegroundYellow_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_Foreground = new System.Windows.Media.SolidColorBrush(Colors.Yellow);
}
private void radioFamilyOriginal_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_FontFamily = initFontFamily;
}
private void radioFamilyTimes_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_FontFamily = new System.Windows.Media.FontFamily("Times New Roman");
}
private void radioFamilyWingDings_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_FontFamily = new System.Windows.Media.FontFamily("WingDings");
}
private void radioSizeOriginal_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_FontSize = initFontSize;
}
private void radioSizeTen_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_FontSize = 10;
}
private void radioSizeTwelve_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_FontSize = 12;
}
private void radioStyleOriginal_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_FontStyle = initFontStyle;
}
private void radioStyleItalic_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_FontStyle = System.Windows.FontStyles.Italic;
}
private void radioWeightOriginal_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_FontWeight = initFontWeight;
}
private void radioWeightBold_CheckedChanged(object sender, EventArgs e)
{
wpfAddressCtrl.MyControl_FontWeight = FontWeights.Bold;
}
Постройте и запустите приложение. Щелкайте различные переключатели, чтобы увидеть соответствующий эффект в составном элементе управления WPF.
См. также
Задачи
Ссылки
Основные понятия
Пошаговое руководство. Размещение составного элемента управления Windows Forms в приложении WPF