Общие сведения о WPF
Платформа Windows Presentation Foundation (WPF) позволяет создавать клиентские приложения для настольных систем Windows с привлекательным пользовательским интерфейсом.
В основе WPF лежит независимый от разрешения векторный модуль визуализации, использующий возможности современного графического оборудования. Возможности этого модуля расширяются с помощью комплексного набора функций разработки приложений, которые включают в себя язык XAML, элементы управления, привязку к данным, макет, двумерную и трехмерную графику, анимацию, стили, шаблоны, документы, мультимедиа, текст и типографические функции. WPF является частью .NET, поэтому вы можете создавать приложения, включающие другие элементы .NET API.
Этот обзор предназначен для новичков: в нем рассматриваются ключевые возможности и понятия WPF.
Программирование с помощью WPF
WPF существует в виде подмножества типов .NET, которые по большей части находятся в пространстве имен System.Windows. Если ранее вы создавали приложения с помощью .NET, используя управляемые технологии, такие как ASP.NET и Windows Forms, основные принципы программирования с помощью WPF должны быть вам знакомы: вы создаете экземпляры классов, задаете свойства, вызываете методы и обрабатываете события — все это с использованием своего любимого языка программирования .NET, например C# или Visual Basic.
WPF включает в себя дополнительные конструкции программирования, которые расширяют возможности свойств и событий: свойства зависимостей и перенаправленные события.
Разметка и код программной части
WPF позволяет разрабатывать приложения, используя как разметку, так и код программной части, что привычно для разработчиков на ASP.NET. Разметка XAML обычно используется для определения внешнего вида приложения, а управляемые языки программирования (код программной части) — для реализации его поведения. Такое разделение внешнего вида и поведения имеет ряд преимуществ.
Затраты на разработку и обслуживание снижаются, так как разметка, определяющая внешний вид, не связана тесно с кодом, обуславливающим поведение.
Повышается эффективность разработки, так как дизайнеры, занимающиеся внешним видом приложения, могут работать параллельно с разработчиками, реализующими поведение приложения.
Глобализация и локализация приложений WPF упрощена.
Разметка
XAML — это язык разметки на основе XML, который служит для определения внешнего вида приложения в декларативной форме. Обычно он используется для создания окон, страниц и пользовательских элементов управления, а также их заполнения элементами управления, фигурами и графическими элементами.
В приведенном ниже примере XAML используется для определения внешнего вида окна, содержащего одну кнопку.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Title="Window with Button"
Width="250" Height="100">
<!-- Add button to window -->
<Button Name="button">Click Me!</Button>
</Window>
Этот код XAML определяет окно и кнопку с помощью элементов Window
и Button
соответственно. Каждый элемент настраивается с помощью атрибутов, например атрибута Window
элемента Title
, определяющего текст заголовка окна. Во время выполнения WPF преобразует элементы и атрибуты, определенные в разметке, в экземпляры классов WPF. Например, элемент Window
преобразуется в экземпляр класса Window , свойство Title которого является значением атрибута Title
.
На рисунке ниже показан пользовательский интерфейс, который определяется кодом XAML из предыдущего примера.
Так как язык XAML основан на XML, создаваемый с его помощью пользовательский интерфейс образует иерархию вложенных элементов, известную как дерево элементов. Дерево элементов обеспечивает логичный и интуитивно понятный способ создания пользовательских интерфейсов и управления ими.
Поддерживающий код
При разработке поведения приложения главной задачей является обеспечение реакции на действия пользователя, включая обработку событий (таких как выбор пункта меню или нажатие на кнопку), и вызов в ответ бизнес-логики и логики доступа к данным. В WPF такое поведение реализуется в коде, связанном с разметкой. Этот код называется кодом программной части. В приведенном ниже примере показана обновленная разметка из предыдущего примера и код программной части.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.AWindow"
Title="Window with Button"
Width="250" Height="100">
<!-- Add button to window -->
<Button Name="button" Click="button_Click">Click Me!</Button>
</Window>
using System.Windows; // Window, RoutedEventArgs, MessageBox
namespace SDKSample
{
public partial class AWindow : Window
{
public AWindow()
{
// InitializeComponent call is required to merge the UI
// that is defined in markup with this class, including
// setting properties and registering event handlers
InitializeComponent();
}
void button_Click(object sender, RoutedEventArgs e)
{
// Show message box when button is clicked.
MessageBox.Show("Hello, Windows Presentation Foundation!");
}
}
}
Namespace SDKSample
Partial Public Class AWindow
Inherits System.Windows.Window
Public Sub New()
' InitializeComponent call is required to merge the UI
' that is defined in markup with this class, including
' setting properties and registering event handlers
InitializeComponent()
End Sub
Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Show message box when button is clicked.
MessageBox.Show("Hello, Windows Presentation Foundation!")
End Sub
End Class
End Namespace
В этом примере в коде программной части реализован класс, производный от класса Window . С помощью атрибута x:Class
разметка связывается с классом в коде программной части. Метод InitializeComponent
вызывается из конструктора класса кода программной части для слияния пользовательского интерфейса, определенного в разметке, с классом кода программной части. (InitializeComponent
создается при построении приложения, поэтому реализовывать его вручную не нужно.) Сочетание x:Class
и InitializeComponent
гарантирует правильную инициализацию реализации при создании. Класс кода программной части также реализует обработчик событий Click кнопки. При нажатии на кнопку обработчик событий выводит окно сообщения, вызывая метод System.Windows.MessageBox.Show .
На рисунке ниже показан результат нажатия на кнопку.
Элементы управления
Возможности взаимодействия с пользователем, обеспечиваемые моделью приложения, реализуются с помощью сконструированных элементов управления. В WPF элемент управления — это общий термин, который относится к категории классов WPF, размещаемых в окне или на странице, имеющих пользовательский интерфейс и реализующих некоторое поведение.
Более подробную информацию см. в разделе Элементы управления.
Функциональная классификация элементов управления WPF
Ниже перечислены встроенные элементы управления WPF.
Кнопки: Button и RepeatButton.
Вывод и выбор дат: Calendar и DatePicker.
Диалоговые окна: OpenFileDialog, PrintDialogи SaveFileDialog.
Рукописный ввод: InkCanvas и InkPresenter.
Документы: DocumentViewer, FlowDocumentPageViewer, FlowDocumentReader, FlowDocumentScrollViewerи StickyNoteControl.
Ввод: TextBox, RichTextBoxи PasswordBox.
Макет: Border, BulletDecorator, Canvas, DockPanel, Expander, Grid, GridView, GridSplitter, GroupBox, Panel, ResizeGrip, Separator, ScrollBar, ScrollViewer, StackPanel, Thumb, Viewbox, VirtualizingStackPanel, Windowи WrapPanel.
Мультимедиа: Image, MediaElementи SoundPlayerAction.
Меню: ContextMenu, Menuи ToolBar.
Навигация: Frame, Hyperlink, Page, NavigationWindowи TabControl.
Выбор: CheckBox, ComboBox, ListBox, RadioButtonи Slider.
Информирование пользователя: AccessText, Label, Popup, ProgressBar, StatusBar, TextBlockи ToolTip.
Ввод данных и команды
Элементы управления чаще всего используются для определения ввода данных пользователем и реагирования на него. Система ввода WPF использует как прямые, так и перенаправленные события для поддержки ввода текста, управления фокусом и определения положения указателя мыши.
Приложения часто предъявляют сложные требования к вводу. WPF предоставляет систему команд, которая отделяет действия по вводу данных пользователем от кода, реагирующего на эти действия.
Макет
При создании пользовательского интерфейса вы компонуете элементы управления, настраивая их расположение и размер. Основным требованием любого макета является адаптация к изменениям размеров окна и параметров экрана. Платформа WPF избавляет вас от необходимости писать код для адаптации макета к таким условиям, предоставляя первоклассную расширяемую систему макета.
Ключевым элементом системы макета является относительное позиционирование, которое упрощает адаптацию к меняющимся характеристикам окна и экрана. Кроме того, система макета управляет взаимодействием между элементами управления для определения макета. Взаимодействие протекает в два этапа: сначала элемент управления сообщает родительскому объекту о требуемом расположении и размере, а затем родительский объект сообщает родительскому элементу, какое пространство он может занять.
Система макета доступна дочерним элементам управления посредством базовых классов WPF. Для стандартных макетов, таких как сетка, наложение и закрепление, в WPF имеется несколько элементов управления макетом.
Canvas: дочерние элементы управления предоставляют собственный макет.
DockPanel: дочерние элементы управления выравниваются по краям панели.
Grid: дочерние элементы управления упорядочиваются по строкам и столбцам.
StackPanel: дочерние элементы управления располагаются с наложением по вертикали или по горизонтали.
VirtualizingStackPanel: дочерние элементы управления виртуализируются и располагаются в линию по горизонтали или по вертикали.
WrapPanel: дочерние элементы управления располагаются в порядке слева направо и переносятся на следующую строку, если не помещаются в текущей.
В приведенном ниже примере элемент управления DockPanel используется для размещения нескольких элементов управления TextBox.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.LayoutWindow"
Title="Layout with the DockPanel" Height="143" Width="319">
<!--DockPanel to layout four text boxes-->
<DockPanel>
<TextBox DockPanel.Dock="Top">Dock = "Top"</TextBox>
<TextBox DockPanel.Dock="Bottom">Dock = "Bottom"</TextBox>
<TextBox DockPanel.Dock="Left">Dock = "Left"</TextBox>
<TextBox Background="White">This TextBox "fills" the remaining space.</TextBox>
</DockPanel>
</Window>
Элемент управления DockPanel позволяет дочерним элементам TextBox сообщать, как они должны быть упорядочены. Для этого в DockPanel реализовано присоединенное свойство Dock
, которое доступно дочерним элементам управления и позволяет каждому из них указывать стиль закрепления.
Примечание.
Свойство, которое реализуется родительским элементом управления для использования дочерними элементами, представляет собой конструкцию WPF, называемую присоединенным свойством.
На рисунке ниже показан результат использования разметки XAML из предыдущего примера.
Привязка данных
Большинство приложений предоставляют пользователям возможность просматривать и редактировать данные. Для приложений WPF задачи хранения данных и доступа к ним уже обеспечиваются такими технологиями, как SQL Server и ADO .NET. После получения доступа к данным и их загрузки в управляемые объекты приложения WPF начинается самое сложное. Фактически этот процесс состоит из двух этапов:
копирование данных из управляемых объектов в элементы управления для их отображения и редактирования;
обеспечение копирования изменений, внесенных в данные с помощью элементов управления, обратно в управляемые объекты.
Чтобы упростить разработку приложений, платформа WPF предоставляет механизм привязки данных для автоматического выполнения этих действий. Основной элемент механизма привязки данных — класс Binding , задачей которого является привязка элемента управления (целевого объекта привязки) к объекту данных (источнику привязки). Эта связь показана на рисунке ниже.
В следующем примере показано, как привязать элемент управления TextBox к экземпляру пользовательского объекта Person
. Реализация Person
показана в следующем коде:
Namespace SDKSample
Class Person
Private _name As String = "No Name"
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
End Class
End Namespace
namespace SDKSample
{
class Person
{
string name = "No Name";
public string Name
{
get { return name; }
set { name = value; }
}
}
}
Приведенная ниже разметка привязывает элемент управления TextBox к экземпляру настраиваемого объекта Person
.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.DataBindingWindow">
<!-- Bind the TextBox to the data source (TextBox.Text to Person.Name) -->
<TextBox Name="personNameTextBox" Text="{Binding Path=Name}" />
</Window>
Imports System.Windows ' Window
Namespace SDKSample
Partial Public Class DataBindingWindow
Inherits Window
Public Sub New()
InitializeComponent()
' Create Person data source
Dim person As Person = New Person()
' Make data source available for binding
Me.DataContext = person
End Sub
End Class
End Namespace
using System.Windows; // Window
namespace SDKSample
{
public partial class DataBindingWindow : Window
{
public DataBindingWindow()
{
InitializeComponent();
// Create Person data source
Person person = new Person();
// Make data source available for binding
this.DataContext = person;
}
}
}
В этом примере экземпляр класса Person
создается в коде программной части и устанавливается в качестве контекста данных для DataBindingWindow
. В разметке свойство Text элемента управления TextBox привязывается к свойству Person.Name
(с помощью синтаксической конструкции «{Binding ... }
» языка XAML). Этот код XAML предписывает платформе WPF привязать элемент управления TextBox к объекту Person
, который хранится в свойстве DataContext окна.
Механизм привязки данных WPF поддерживает дополнительные возможности, включая проверку, сортировку, фильтрацию и группировку. Кроме того, привязка данных поддерживает использование шаблонов данных с целью создания настраиваемого пользовательского интерфейса для связанных данных, если пользовательский интерфейс на основе стандартных элементов управления WPF не удовлетворяет требованиям.
Более подробную информацию см. в разделе Общие сведения о привязке данных.
Графика
Платформа WPF предоставляет широкий, гибкий и масштабируемый набор графических функций, который обладает перечисленными ниже преимуществами.
Независимость графики от разрешения и устройства. Основной единицей измерения в графической системе WPF является аппаратно-независимый пиксель, размер которого составляет 1/96 дюйма вне зависимости от разрешения экрана. Это создает основу для независимой от разрешения и аппаратной платформы отрисовки. Каждый аппаратно-независимый пиксель автоматически масштабируется в соответствии с заданным в системе количеством точек на дюйм (DPI).
Повышение точности. Система координат WPF основана на числах двойной точности с плавающей запятой, а не числах одинарной точности. Значения преобразования и прозрачности также выражаются числами двойной точности. Платформа WPF также поддерживает широкую цветовую палитру (scRGB) и имеет встроенную поддержку управления входными данными из разных цветовых схем.
Расширенная поддержка графики и анимации. Платформа WPF упрощает программирование графики, автоматически управляя анимированными сценами. Вам не нужно беспокоиться об обработке сцен, циклах отрисовки и билинейной интерполяции. Кроме того, WPF обеспечивает поддержку проверки попадания и полную поддержку альфа-версии компоновки.
Аппаратное ускорение. Система графики WPF использует возможности графического оборудования, чтобы снизить нагрузку на ЦП.
Двумерные фигуры
WPF предоставляет библиотеку стандартных векторных двумерных фигур, таких как прямоугольники и эллипсы, которые показаны на рисунке ниже.
Интересной особенностью фигур является то, что они предназначены не только для отображения. В них реализованы многие возможности элементов управления, включая ввод с клавиатуры и с помощью мыши. В приведенном ниже примере показана обработка события MouseUp объекта Ellipse.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.EllipseEventHandlingWindow"
Title="Click the Ellipse">
<Ellipse Name="clickableEllipse" Fill="Blue" MouseUp="clickableEllipse_MouseUp" />
</Window>
Imports System.Windows ' Window, MessageBox
Imports System.Windows.Input ' MouseButtonEventArgs
Namespace SDKSample
Public Class EllipseEventHandlingWindow
Inherits Window
Public Sub New()
InitializeComponent()
End Sub
Private Sub clickableEllipse_MouseUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
MessageBox.Show("You clicked the ellipse!")
End Sub
End Class
End Namespace
using System.Windows; // Window, MessageBox
using System.Windows.Input; // MouseButtonEventHandler
namespace SDKSample
{
public partial class EllipseEventHandlingWindow : Window
{
public EllipseEventHandlingWindow()
{
InitializeComponent();
}
void clickableEllipse_MouseUp(object sender, MouseButtonEventArgs e)
{
// Display a message
MessageBox.Show("You clicked the ellipse!");
}
}
}
На следующем рисунке показан результат выполнения предыдущего кода.
Более подробную информацию см. в разделе Обзор фигур и базовых средств рисования в приложении WPF.
Двумерные геометрические объекты
Двумерные фигуры, предоставляемые WPF, включают в себя стандартный набор базовых фигур. Однако вам может потребоваться создать собственные фигуры, чтобы упростить разработку пользовательского интерфейса. Для этой цели WPF предоставляет геометрические объекты. На рисунке ниже демонстрируется использование геометрических объектов для создания пользовательской фигуры, которую можно нарисовать напрямую, применять как кисть или использовать для обрезки других фигур и элементов управления.
ОбъектыPath можно использовать для рисования замкнутых и незамкнутых фигур, нескольких фигур и даже криволинейных фигур.
Объекты Geometry можно использовать для обрезки, проверки попадания и отрисовки двумерных графических данных.
Дополнительные сведения см. в разделе Общие сведения о классе Geometry.
Двумерные эффекты
В число возможностей двумерной графики WPF входят визуальные эффекты, такие как градиенты, растровые изображения, рисунки, рисование с видео, вращение, масштабирование и наклон. Применение всех этих эффектов обеспечивается с помощью кистей. На рисунке ниже показан ряд примеров.
Дополнительные сведения см. в разделе Общие сведения о кистях WPF.
Трехмерная отрисовка
Платформа WPF также предоставляет возможности трехмерной отрисовки, которые интегрированы с возможностями двумерной графики, что позволяет создавать более интересные и яркие пользовательские интерфейсы. Например, на рисунке ниже показаны двумерные изображения, наложенные на трехмерные объекты.
Дополнительные сведения см. в статье Обзор трехмерной графики.
Анимация
Поддержка анимации в WPF позволяет применять к элементам управления такие эффекты, как увеличение, дрожание, вращение и исчезание, создавать интересные эффекты смены страниц и другие эффекты. Вы можете анимировать большинство классов WPF, даже настраиваемые классы. На рисунке ниже показана простая анимация в действии.
Дополнительные сведения см. в разделе Общие сведения об эффектах анимации.
Мультимедиа
Одни из способов передачи более информативного содержимого — использовать аудиовизуальные средства. WPF обеспечивает специальную поддержку изображений, видео и звука.
изображения;
Изображения присутствуют в большинстве приложений, и платформа WPF предоставляет несколько способов их использования. На рисунке ниже показан пользовательский интерфейс со списком, содержащим эскизы. При выборе эскиза изображение отображается в полном размере.
Дополнительные сведения см. в разделе Общие сведения об обработке изображений.
Видео и звук
Элемент управления MediaElement позволяет воспроизводить как видео, так и звук и достаточно гибок для того, чтобы служить основой для пользовательского мультимедиапроигрывателя. Приведенная ниже разметка XAML реализует мультимедиапроигрыватель.
<MediaElement
Name="myMediaElement"
Source="media/wpf.wmv"
LoadedBehavior="Manual"
Width="350" Height="250" />
На следующем рисунке показано окно с элементом управления MediaElement в действии:
Дополнительные сведения см. в разделе Графика и мультимедиа.
Текст и типографическая разметка
Чтобы упростить высококачественную отрисовку текста, платформа WPF предоставляет следующие возможности:
поддержка шрифтов OpenType;
усовершенствования ClearType;
высокая производительность за счет аппаратного ускорения;
интеграция текста с мультимедиа, графикой и анимацией;
поддержка международных шрифтов и резервных механизмов.
В качестве демонстрации интеграции текста с графикой на рисунке ниже показано применение эффектов оформления текста.
Более подробную информацию см. в разделе Типографическая разметка в Windows Presentation Foundation.
Настройка приложений WPF
До сих пор мы рассматривали основные строительные блоки WPF для разработки приложений. Для размещения и предоставления содержимого приложения, состоящего в основном из элементов управления, используется модель приложения. Для упрощения размещения элементов управления в пользовательском интерфейсе и сохранения их компоновки в случае изменения размера окна или параметров экрана используется система макета WPF. Так как большинство приложений предоставляют пользователям возможность взаимодействовать с данными, для сокращения объема работы, необходимой для интеграции пользовательского интерфейса с данными, используется привязка данных. Чтобы улучшить внешний вид приложения, используется широкий ряд средств графики, анимации и мультимедиа, предоставляемый платформой WPF.
Однако зачастую этих основных средств недостаточно для создания уникального и визуально привлекательного пользовательского интерфейса. Стандартные элементы управления WPF могут не сочетаться с требуемым оформлением вашего приложения. Данные могут отображаться не самым эффективным образом. Пользовательскому интерфейсу вашего приложения может в целом не подходить внешний вид тем Windows по умолчанию. Наряду с другими типами расширяемости, технологии представления во многих случаях требуется визуальная расширяемость.
По этой причине WPF предоставляет разнообразные механизмы создания уникальных пользовательских интерфейсов, включая модель мультимедийного содержимого для элементов управления, триггеры, шаблоны элементов управления и данных, стили, ресурсы пользовательского интерфейса, темы и обложки.
Модель содержимого
Основным назначением большинства элементов управления WPF является отображение содержимого. В WPF тип и число элементов, составляющих содержимое элемента управления, называются моделью содержимогоэлемента управления. Некоторые элементы могут содержать только один объект и только один тип содержимого. Например, содержимым элемента управления TextBox является строковое значение, присвоенное свойству Text . В следующем примере задается содержимое элемента управления TextBox:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.TextBoxContentWindow"
Title="TextBox Content">
<TextBox Text="This is the content of a TextBox." />
</Window>
На следующем рисунке показан результат:
Другие элементы управления, однако, могут содержать несколько объектов с различным типом содержимого. Содержимым элемента управления Button, определяемым свойством Content, могут быть различные объекты, в том числе элементы управления макетом, текст, изображения и фигуры. В следующем примере показан элемент управления Button, содержащий DockPanel, Label, Border и MediaElement:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.ButtonContentWindow"
Title="Button Content">
<Button Margin="20">
<!-- Button Content -->
<DockPanel Width="200" Height="180">
<Label DockPanel.Dock="Top" HorizontalAlignment="Center">Click Me!</Label>
<Border Background="Black" BorderBrush="Yellow" BorderThickness="2"
CornerRadius="2" Margin="5">
<MediaElement Source="media/wpf.wmv" Stretch="Fill" />
</Border>
</DockPanel>
</Button>
</Window>
На следующем рисунке показано содержимое этой кнопки:
Дополнительную информацию о типах содержимого, поддерживаемого различными элементами управления, см. в разделе Модель содержимого WPF.
Триггеры
Хотя основным назначением разметки XAML является определение внешнего вида приложения, ее также можно использовать для реализации некоторых аспектов поведения приложения. Один из примеров — изменение внешнего вида приложения с помощью триггеров при выполнении пользователем определенных действий. Дополнительные сведения см. в разделе Стили и шаблоны.
Шаблоны элементов управления
Пользовательские интерфейсы по умолчанию для элементов управления WPF обычно формируются на основе других элементов управления и фигур. Например, элемент управления Button состоит из элементов управления ButtonChrome и ContentPresenter . ButtonChrome обеспечивает стандартный внешний вид кнопки, а ContentPresenter служит для вывода ее содержимого, определяемого свойством Content .
Иногда внешний вид элемента управления по умолчанию может не согласовываться с общим оформлением приложения. В этом случае можно использовать ControlTemplate для изменения пользовательского интерфейса элемента управления, не меняя его содержимое и поведение.
В приведенном ниже примере показано, как изменить внешний вид элемента управления Button с помощью ControlTemplate.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.ControlTemplateButtonWindow"
Title="Button with Control Template" Height="158" Width="290">
<!-- Button using an ellipse -->
<Button Content="Click Me!" Click="button_Click">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Margin="5">
<Ellipse Stroke="DarkBlue" StrokeThickness="2">
<Ellipse.Fill>
<RadialGradientBrush Center="0.3,0.2" RadiusX="0.5" RadiusY="0.5">
<GradientStop Color="Azure" Offset="0.1" />
<GradientStop Color="CornflowerBlue" Offset="1.1" />
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ContentPresenter Name="content" HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</Window>
using System.Windows; // Window, RoutedEventArgs, MessageBox
namespace SDKSample
{
public partial class ControlTemplateButtonWindow : Window
{
public ControlTemplateButtonWindow()
{
InitializeComponent();
}
void button_Click(object sender, RoutedEventArgs e)
{
// Show message box when button is clicked
MessageBox.Show("Hello, Windows Presentation Foundation!");
}
}
}
Imports System.Windows ' Window, RoutedEventArgs, MessageBox
Namespace SDKSample
Public Class ControlTemplateButtonWindow
Inherits Window
Public Sub New()
InitializeComponent()
End Sub
Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
MessageBox.Show("Hello, Windows Presentation Foundation!")
End Sub
End Class
End Namespace
В этом примере пользовательский интерфейс кнопки по умолчанию заменяется элементом Ellipse, имеющим темно-синюю границу и заполнение, определяемое RadialGradientBrush. В элементе управления ContentPresenter выводится содержимое элемента Button — текст "Click Me!". При нажатии элемента Button по-прежнему вызывается событие Click, как часть поведения по умолчанию элемента управления Button. Результат показан на рисунке ниже.
Шаблоны данных
В то время как шаблон элемента управления позволяет определять внешний вид элемента управления, шаблон данных дает возможность настраивать оформление его содержимого. Шаблоны данных часто используются для оптимизации отображения привязанных данных. На рисунке ниже показано стандартное оформление элемента управления ListBox, привязанного к коллекции объектов Task
, в котором у каждой задачи есть название, описание и приоритет.
Оформление по умолчанию является стандартным для элемента управления ListBox. Однако оно предполагает, что для каждой задачи отображается только ее название. Чтобы отобразить название, описание и приоритет задачи, нужно изменить оформление по умолчанию для элементов списка, привязанных к элементу управления ListBox , с помощью DataTemplate. Приведенный ниже код XAML определяет такой шаблон DataTemplate, который применяется к каждой задаче с помощью атрибута ItemTemplate.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.DataTemplateWindow"
Title="With a Data Template">
<Window.Resources>
<!-- Data Template (applied to each bound task item in the task collection) -->
<DataTemplate x:Key="myTaskTemplate">
<Border Name="border" BorderBrush="DarkSlateBlue" BorderThickness="2"
CornerRadius="2" Padding="5" Margin="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="Task Name:"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=TaskName}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Padding="0,0,5,0" Text="Description:"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}"/>
<TextBlock Grid.Row="2" Grid.Column="0" Padding="0,0,5,0" Text="Priority:"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/>
</Grid>
</Border>
</DataTemplate>
</Window.Resources>
<!-- UI -->
<DockPanel>
<!-- Title -->
<Label DockPanel.Dock="Top" FontSize="18" Margin="5" Content="My Task List:"/>
<!-- Data template is specified by the ItemTemplate attribute -->
<ListBox
ItemsSource="{Binding}"
ItemTemplate="{StaticResource myTaskTemplate}"
HorizontalContentAlignment="Stretch"
IsSynchronizedWithCurrentItem="True"
Margin="5,0,5,5" />
</DockPanel>
</Window>
На следующем рисунке показан результат использования этого кода:
Обратите внимание на то, что элемент управления ListBox сохранил свое поведение и общий внешний вид. Изменилось только оформление содержимого, отображаемого в списке.
Дополнительные сведения см. в разделе Общие сведения о шаблонах данных.
Стили
Стили позволяют разработчикам и дизайнерам стандартизировать внешний вид своего продукта. Платформа WPF предоставляет строгую модель стилей, в основе которой лежит элемент Style . В приведенном ниже примере создается стиль, который задает Orange
в качестве цвета фона для каждого элемента управления Button в окне.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.StyleWindow"
Title="Styles">
<Window.Resources>
<!-- Style that will be applied to all buttons for this window -->
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Orange" />
<Setter Property="BorderBrush" Value="Crimson" />
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Margin" Value="5" />
</Style>
</Window.Resources>
<StackPanel>
<!-- This button will have the style applied to it -->
<Button>Click Me!</Button>
<!-- This label will not have the style applied to it -->
<Label>Don't Click Me!</Label>
<!-- This button will have the style applied to it -->
<Button>Click Me!</Button>
</StackPanel>
</Window>
Так как этот стиль предназначен для всех элементов управления Button, он автоматически применяется ко всем кнопкам в окне, как показано на рисунке ниже.
Дополнительные сведения см. в разделе Стили и шаблоны.
Ресурсы
Элементы управления в приложении должны иметь одинаковое оформление, которое может включать любые элементы: от шрифтов и цвета фона до шаблонов элементов управления, шаблонов данных и стилей. Благодаря поддержке ресурсов пользовательского интерфейса в WPF можно инкапсулировать эти ресурсы в одном месте для повторного использования.
В приведенном ниже примере определяется общий цвет фона для элементов управления Button и Label.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.ResourcesWindow"
Title="Resources Window">
<!-- Define window-scoped background color resource -->
<Window.Resources>
<SolidColorBrush x:Key="defaultBackground" Color="Red" />
</Window.Resources>
<!-- Button background is defined by window-scoped resource -->
<Button Background="{StaticResource defaultBackground}">One Button</Button>
<!-- Label background is defined by window-scoped resource -->
<Label Background="{StaticResource defaultBackground}">One Label</Label>
</Window>
Ресурс цвета фона реализуется с помощью элемента свойства Window.Resources
. Этот ресурс доступен всем дочерним элементам объекта Window. Существует ряд различных областей действия ресурсов. Некоторые из них перечислены ниже в порядке их разрешения.
Отдельный элемент управления (с использованием наследуемого свойства System.Windows.FrameworkElement.Resources ).
Window или Page (также с использованием наследуемого свойства System.Windows.FrameworkElement.Resources ).
Application (с использованием свойства System.Windows.Application.Resources ).
Разнообразие областей действия обеспечивает гибкость в отношении способов определения ресурсов и предоставления доступа к ним.
Помимо прямого сопоставления ресурсов с определенной областью действия, можно упаковать один или несколько ресурсов с помощью отдельного объекта ResourceDictionary , на который можно ссылаться в других частях приложения. Так, в следующем примере определяется цвет фона по умолчанию в словаре ресурсов:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Define background color resource -->
<SolidColorBrush x:Key="defaultBackground" Color="Red" />
<!-- Define other resources -->
</ResourceDictionary>
В приведенном ниже примере используется ссылка на словарь ресурсов, определенный в предыдущем примере, что позволяет использовать словарь в рамках всего приложения.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="BackgroundColorResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Ресурсы и словари ресурсов лежат в основе реализованной в WPF поддержки тем и обложек.
Дополнительные сведения см. в статье о ресурсах DSC.
Пользовательские элементы управления
Хотя WPF предоставляет множество возможностей настройки, могут возникнуть ситуации, когда существующие элементы управления WPF не удовлетворяют потребности вашего приложения или его пользователей. Это может произойти в указанных ниже случаях.
Требуемый пользовательский интерфейс нельзя создать, настроив внешний вид существующих элементов, реализованных в WPF.
Требуемое поведение не поддерживается существующими элементами, реализованными в WPF, или его поддержка представляет трудность.
В такой ситуации вы можете воспользоваться одной из трех моделей WPF, чтоб создать новый элемент управления. Каждая модель предназначена для определенного сценария и предполагает, что пользовательский элемент управления наследуется от определенного базового класса WPF. Ниже перечислены эти три модели.
Модель пользовательского элемента управления. Пользовательский элемент управления наследуется от UserControl и составляется из одного или нескольких других элементов управления.
Модель элемента управления. Пользовательский элемент управления наследуется от Control и используется для создания реализаций, в которых поведение и внешний вид разделяются с помощью шаблонов, как в большинстве элементов управления WPF. Наследование от класса Control обеспечивает большую гибкость при создании собственного пользовательского интерфейса, чем пользовательские элементы управления, но может потребовать больших усилий.
Модель элемента платформы. Пользовательский элемент управления наследуется от класса FrameworkElement , если его внешний вид определяется пользовательской логикой отрисовки, а не шаблонами.
В приведенном ниже примере показан пользовательский элемент управления для увеличения или уменьшения числового значения, наследуемый от UserControl.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.NumericUpDown">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- Value text box -->
<Border BorderThickness="1" BorderBrush="Gray" Margin="2" Grid.RowSpan="2"
VerticalAlignment="Center" HorizontalAlignment="Stretch">
<TextBlock Name="valueText" Width="60" TextAlignment="Right" Padding="5"/>
</Border>
<!-- Up/Down buttons -->
<RepeatButton Name="upButton" Click="upButton_Click" Grid.Column="1"
Grid.Row="0">Up</RepeatButton>
<RepeatButton Name="downButton" Click="downButton_Click" Grid.Column="1"
Grid.Row="1">Down</RepeatButton>
</Grid>
</UserControl>
using System; // EventArgs
using System.Windows; // DependencyObject, DependencyPropertyChangedEventArgs,
// FrameworkPropertyMetadata, PropertyChangedCallback,
// RoutedPropertyChangedEventArgs
using System.Windows.Controls; // UserControl
namespace SDKSample
{
public partial class NumericUpDown : UserControl
{
// NumericUpDown user control implementation
}
}
imports System 'EventArgs
imports System.Windows 'DependencyObject, DependencyPropertyChangedEventArgs,
' FrameworkPropertyMetadata, PropertyChangedCallback,
' RoutedPropertyChangedEventArgs
imports System.Windows.Controls 'UserControl
Namespace SDKSample
' Interaction logic for NumericUpDown.xaml
Partial Public Class NumericUpDown
Inherits System.Windows.Controls.UserControl
'NumericUpDown user control implementation
End Class
End Namespace
В следующем примере показан код XAML, необходимый для включения пользовательского элемента управления в Window:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.UserControlWindow"
xmlns:local="clr-namespace:SDKSample"
Title="User Control Window">
<!-- Numeric Up/Down user control -->
<local:NumericUpDown />
</Window>
На рисунке ниже показан элемент управления NumericUpDown
, размещенный в окне Window.
Дополнительные сведения о пользовательских элементах управления см. в разделе Общие сведения о разработке управления.
Рекомендации по использованию WPF
Как и любую другую платформу разработки, WPF можно использовать разными способами для получения нужного результата. Чтобы ваши приложения WPF обеспечивали требуемый уровень удобства и отвечали потребностям пользователей в целом, следует придерживаться рекомендаций в отношении специальных возможностей, глобализации, локализации и производительности. Дополнительные сведения см. в разделе:
- Специальные возможности
- Глобализация и локализация WPF
- Производительность приложения WPF
- Безопасность WPF
Следующие шаги
Мы рассмотрели основные возможности WPF. Теперь пора приступить к созданию первого приложения WPF.
См. также
.NET Desktop feedback