Что такое Windows Presentation Foundation (WPF .NET)What is Windows Presentation Foundation (WPF .NET)

Добро пожаловать в руководство по классическим приложениям для Windows Presentation Foundation (WPF), платформы пользовательского интерфейса для создания клиентских приложений для настольных систем под управлением Windows.Welcome to the Desktop Guide for Windows Presentation Foundation (WPF), a UI framework that creates desktop client applications for Windows. Платформа разработки WPF поддерживает широкий набор компонентов для разработки приложений, включая модель приложения, элементы управления, графику и привязку данных.The WPF development platform supports a broad set of application development features, including an application model, controls, graphics, and data binding. WPF использует расширяемый язык разметки для приложений (XAML), чтобы предоставить декларативную модель для программирования приложений.WPF uses Extensible Application Markup Language (XAML) to provide a declarative model for application programming.

Важно!

Документация для Руководства по рабочему столу по .NET 5 (и .NET Core) находится в разработке.The Desktop Guide documentation for .NET 5 (and .NET Core) is under construction.

Существует две реализации WPF:There are two implementations of WPF:

  1. Реализация с открытым исходным кодом, размещенная на GitHub.The open-source implementation hosted on GitHub. Эта версия работает на платформе .NET Core 3.0.This version runs on .NET Core 3.0. Для работы визуального конструктора WPF для XAML требуется версия Visual Studio 2019 не ниже 16.3.The WPF Visual Designer for XAML requires, at a minimum, Visual Studio 2019 version 16.3.

  2. Реализация .NET Framework, поддерживаемая в Visual Studio 2019 и Visual Studio 2017.The .NET Framework implementation that's supported by Visual Studio 2019 and Visual Studio 2017.

Это руководство по классическим приложениям ориентировано на .NET Core 3.0 и WPF.This Desktop Guide is written for .NET Core 3.0 and WPF. Дополнительные сведения о доступной документации по .NET Framework см. в статье Платформа Windows Presentation Foundation.For more information about the existing documentation for WPF with the .NET Framework, see Framework Windows Presentation Foundation.

XAMLXAML

XAML — это декларативный язык на основе XML, который используется на платформе WPF для определения ресурсов или элементов пользовательского интерфейса, а также решения других задач.XAML is a declarative XML-based language that WPF uses for things such as defining resources or UI elements. Определяемые в XAML элементы представляют создание экземпляров объектов из сборки.Elements defined in XAML represent the instantiation of objects from an assembly. В этом заключается отличие XAML от большинства других языков разметки, которые представляют собой интерпретируемые во время выполнения языки без прямой связи с резервной системой типов.XAML is unlike most other markup languages, which are interpreted at runtime without a direct tie to a backing type system.

В следующем примере показано, как можно создать кнопку как часть пользовательского интерфейса.The following example shows how you would create a button as part of a UI. На этом примере демонстрируется принцип представления объекта в XAML. Здесь Button — это тип, а Content — свойство.This example is intended to give you an idea of how XAML represents an object, where Button is the type and Content is a property.

<StackPanel>
    <Button Content="Click Me!" />
</StackPanel>

Расширения XAMLXAML extensions

XAML поддерживает синтаксис для расширений разметки.XAML provides syntax for markup extensions. Расширения разметки можно использовать для предоставления значений свойств в форме атрибутов, элементов свойств или обоими способами.Markup extensions can be used to provide values for properties in attribute form, property-element form, or both.

Например, в приведенном выше коде XAML определяется кнопка, для которой в качестве отображаемого содержимого используется строка символов "Click Me!". При этом вместо нее может использоваться расширение разметки.For example, the previous XAML code defined a button with the visible content set to the literal string "Click Me!", but the content can be instead set by a supported markup extension. Расширение разметки определяется с помощью открывающих и закрывающих фигурных скобок { }.A markup extension is defined with opening and closing curly braces { }. Затем тип расширения разметки определяется по токену строки, следующему сразу после открывающей фигурной скобки.The type of markup extension is then identified by the string token immediately following the opening curly brace.

<StackPanel>
    <Button Content="{MarkupType}" />
</StackPanel>

В WPF поддерживаются разные расширения разметки для XAML, например {Binding} для привязки данных.WPF provides different markup extensions for XAML such as {Binding} for data binding.

Дополнительные сведения см. в разделе Расширения разметки и XAML WPF.For more information, see Markup Extensions and WPF XAML.

Система свойствProperty system

WPF предоставляет набор служб, которые можно использовать для расширения функциональных возможностей свойства типа.WPF provides a set of services that can be used to extend the functionality of a type's property. В совокупности эти службы называются системой свойств WPF.Collectively, these services are referred to as the WPF property system. Свойство, поддерживаемое системой свойств WPF, называется свойством зависимостей.A property that is backed by the WPF property system is known as a dependency property.

Свойства зависимостей дополняют функциональные возможности свойства, предоставляя тип DependencyProperty для реализации поддержки свойства.Dependency properties extend property functionality by providing the DependencyProperty type that backs a property. Тип свойства зависимостей является альтернативной реализацией стандартного шаблона для резервирования свойства с закрытым полем.The dependency property type is an alternative implementation of the standard pattern of backing the property with a private field.

Свойство зависимостейDependency property

В WPF свойства зависимостей обычно представляются как стандартные свойства .NET.In WPF, dependency properties are typically exposed as standard .NET properties. На базовом уровне можно взаимодействовать с этими свойствами непосредственно и не знать, что они реализуются как свойства зависимостей.At a basic level, you could interact with these properties directly and never know that they're implemented as a dependency property.

Свойства зависимостей предназначены для предоставления способа вычисления значения свойства по значениям других входных данных.The purpose of dependency properties is to provide a way to compute the value of a property based on the value of other inputs. Такие входные данные могут включать в себя системные свойства, такие как темы и предпочтения пользователя, а также JIT-свойства из привязок данных и анимаций.These other inputs might include system properties such as themes and user preferences, or just-in-time property from data binding and animations.

Свойство зависимостей может быть реализовано для проверки, определения значений по умолчанию и выполнения обратных вызовов, которые позволяют отслеживать изменения в других свойствах.A dependency property can be implemented to provide validation, default values, and callbacks that monitor changes to other properties. Производные классы также могут изменять некоторые специфические характеристики существующего свойства путем переопределения метаданных свойства зависимостей вместо того, чтобы создавать новые или переопределять существующие свойства.Derived classes can also change some specific characteristics of an existing property by overriding dependency property metadata, rather than creating a new property or overriding an existing property.

Объект зависимостиDependency object

Еще одним важным элементом системы свойств WPF является DependencyObject.Another type that is key to the WPF property system is the DependencyObject. Этот тип определяет базовый класс для регистрации свойства зависимостей и использования в качестве его владельца.This type defines the base class that can register and own a dependency property. Методы GetValue и SetValue обеспечивают реализацию резервирования свойства зависимостей для экземпляра объекта зависимости.The GetValue and SetValue methods provide the backing implementation of the dependency property for the dependency object instance.

В следующем примере показан объект зависимости, который определяет один идентификатор свойства зависимости с именем ValueProperty.The following example shows a dependency object that defines a single dependency property identifier named ValueProperty. Свойство зависимостей создается с использованием свойства .NET Value.The dependency property is created with the Value .NET property.

public class TextField: DependencyObject
{
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(string), typeof(TextField), new PropertyMetadata(""));

    public string Value
    {
        get { return (string)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }
}

Свойство зависимостей определяется как статический член типа объекта зависимости, как TextField в приведенном выше примере.The dependency property is defined as a static member of a dependency object type, such as TextField in example above. Свойство зависимостей должно быть зарегистрировано в объекте зависимости.The dependency property must be registered with the dependency object.

В приведенном выше примере свойство Value заключает в оболочку свойство зависимостей, предоставляя стандартный шаблон свойства .NET, который вы наверняка уже использовали.The Value property in the example above wraps the dependency property, providing the standard .NET property pattern you're probably used to.

СобытияEvents

WPF предоставляет систему событий, размещаемую поверх событий среды CLR .NET, с которыми вы уже знакомы.WPF provides an eventing system that is layered on top of the .NET common language runtime (CLR) events you're familiar with. Такие события WPF называются перенаправленными событиями.These WPF events are called routed events.

Перенаправленное событие — это событие CLR, поддерживаемое экземпляром класса RoutedEvent и регистрируемое в системе событий WPF.A routed event is a CLR event that is backed by an instance of the RoutedEvent class and registered with the WPF event system. Экземпляр RoutedEvent, полученный из регистрации события, обычно сохраняется в качестве поля public static readonly класса, который регистрирует перенаправленное событие и, таким образом, владеет им.The RoutedEvent instance obtained from event registration is typically retained as a public static readonly field member of the class that registers, and thus owns the routed event. Соединение с событием CLR с таким же именем (которое иногда называется событием программы-оболочки) выполняется путем переопределения реализаций add и remove для события CLR.The connection to the identically named CLR event (which is sometimes termed the wrapper event) is accomplished by overriding the add and remove implementations for the CLR event. Концептуально механизм подключения и резервирования перенаправленного события похож на то, как свойство зависимостей является свойством CLR, которое резервируется классом DependencyProperty и регистрируется в системе свойств WPF.The routed event backing and connection mechanism is conceptually similar to how a dependency property is a CLR property that is backed by the DependencyProperty class and registered with the WPF property system.

Основное преимущество системы перенаправленных событий заключается в том, что события поднимаются по дереву элементов элемента управления в поисках обработчика.The main advantage of the routed event system is that events are bubbled up the control element tree looking for a handler. Например, поскольку в WPF реализована обширная модель управления содержимым, вы можете задать элемент управления "Изображение" в качестве содержимого элемента управления "Кнопка".For example, because WPF has a rich content model, you set an image control as the content of a button control. При щелчке кнопки мыши на элементе управления "Изображение" вы предполагаете, что будут использоваться события мыши, в результате чего срабатывает проверка попаданий и вызывается событие Click кнопки.When the mouse is clicked on the image control, you would expect it to consume the mouse events, and thus break the hit-tests that cause a button to invoke the Click event. В традиционной модели событий CLR это ограничение можно обойти, присоединив один и тот же обработчик к изображению и кнопке.In a traditional CLR eventing model, you would work around this limitation by attaching the same handler to both the image and the button. Однако в системе перенаправленных событий события мыши, вызываемые для элемента управления "Изображение" (например, при выборе изображения), поднимаются по дереву до родительского элемента управления "Кнопка".But with the routed event system, the mouse events invoked on the image control (such as selecting it) bubble up to the parent button control.

привязка данных,Data binding

Привязка данных WPF предоставляет приложениям простой и последовательный способ представления данных и взаимодействия с ними.WPF data binding provides a simple and consistent way for applications to present and interact with data. Элемент можно привязывать к данным из источников самого разного типа в форме объектов CLR и XML.Elements can be bound to data from different types of data sources in the form of common language runtime (CLR) objects and XML. WPF также предоставляет механизм передачи данных с помощью операций перетаскивания.WPF also provides a mechanism for the transfer of data through drag-and-drop operations.

Привязка данных — это процесс установления соединения между пользовательским интерфейсом приложения и бизнес-логикой.Data binding is the process that establishes a connection between the application UI and business logic. Если для привязки заданы правильные настройки, а изменения значений данных сопровождаются правильными уведомлениями, привязанные к данным элементы автоматически отражают изменения.If the binding has the correct settings and the data provides the proper notifications, then, when the data changes its value, the elements that bound to the data reflect changes automatically. Привязка данных может также означать, что если внешнее представление данных в элементе изменяется, то базовые данные могут автоматически обновляться для отражения изменений.Data binding can also mean that if an outer representation of the data in an element changes, then the underlying data is automatically updated to reflect the change. Например, если пользователь изменяет значение в элементе TextBox, базовое значение данных автоматически обновляется, чтобы отразить это изменение.For example, if the user edits the value in a TextBox element, the underlying data value is automatically updated to reflect that change.

Привязку данных можно настроить в XAML с помощью расширения разметки {Binding}.Data binding can be configured in XAML through the {Binding} markup extension. В следующем примере показана привязка к свойству ButtonText объекта данных.The following example demonstrates binding to a data object's ButtonText property. В случае сбоя привязки используется значение Click Me!.If that binding fails, the value of Click Me! is used.

<StackPanel>
    <Button Content="{Binding ButtonText, FallbackValue='Click Me!'}" />
</StackPanel>

Более подробную информацию см. в разделе Общие сведения о привязке данных.For more information, see Data binding overview.

Компоненты пользовательского интерфейсаUI components

WPF содержит большинство распространенных компонентов пользовательского интерфейса, которые используются практически во всех Windows-приложениях, например Button, Label, TextBox, Menu и ListBox.WPF provides many of the common UI components that are used in almost every Windows application, such as Button, Label, TextBox, Menu, and ListBox. Исторически эти объекты называются элементами управления.Historically, these objects have been referred to as controls. Хотя в пакете SDK для WPF по-прежнему используется термин "элемент управления" для обобщенного обозначения любого класса, который представляет видимый объект в приложении, важно отметить, что класс с визуальным представлением не обязательно должен наследовать от класса Control.While the WPF SDK continues to use the term control to loosely mean any class that represents a visible object in an application, it's important to note that a class doesn't need to inherit from the Control class to have a visible presence. Классы, наследуемые от класса Control, содержат шаблон ControlTemplate, который позволяет существенно изменить внешний вид элемента управления, не создавая новый подкласс.Classes that inherit from the Control class contain a ControlTemplate, which allows the consumer of a control to radically change the control's appearance without having to create a new subclass.

Стили и шаблоныStyles and templates

Стилизация и использование шаблонов WPF относятся к набору возможностей (стили, шаблоны, триггеры и раскадровки), которые позволяют разработчикам приложений, документации или пользовательского интерфейса создавать визуально привлекательные приложения, а также определять стандартизированный внешний вид своих продуктов.WPF styling and templating refer to a suite of features (styles, templates, triggers, and storyboards) that allow an application, document, or UI designer to create visually compelling applications and to standardize on a particular look for their product.

Еще одна особенность модели стилизации WPF заключается в разделении представления и логики. Это означает, что дизайнеры могут работать над внешним видом приложения с использованием XAML, тогда как разработчики могут определять логику программирования другим способом.Another feature of the WPF styling model is the separation of presentation and logic, which means designers can work on the appearance of an application with XAML while developers work on the programming logic elsewhere.

Также важно иметь представление о ресурсах, которые позволяют повторно использовать стили и шаблоны.In addition, it's important to understand resources, which are what enable styles and templates to be reused.

Дополнительные сведения см. в разделе Стили и шаблоны.For more information, see Styles and templates.

РесурсыResources

Ресурс WPF — это объект, который можно повторно использовать в разных местах приложения.WPF resources are objects that can be reused in different places in your application. В качестве примеров ресурсов можно привести стили, шаблоны и цветные кисти.Examples of resources include styles, templates, and color brushes. Определять ресурсы и задавать ссылки на них можно как в коде, так и в формате XAML.Resources can be both defined and referenced in code and in XAML format.

Каждый элемент уровня платформы (FrameworkElement или FrameworkContentElement) имеет свойство Resources, которое представляет собой тип ResourceDictionary, содержащий определенные ресурсы.Every framework-level element (FrameworkElement or FrameworkContentElement) has a Resources property (which is a ResourceDictionary type) that contains defined resources. Поскольку все элементы наследуются от элемента уровня платформы, для определения ресурсов можно использовать любые элементы.Since all elements inherit from a framework-level element, all elements can define resources. Тем не менее, чаще всего ресурсы определяются в корневом элементе документа XAML.It's most common, however, to define resources on a root element of a XAML document.

Следующие шагиNext steps