Практикум WPF — введение в WPF и XAML
Практикум, шаг 1 из 6. Фиксируем базовую модель WPF перед MVVM и клиент-серверной частью. Полный локальный практикум с нуля — 119.md; обзор платформы Windows — 116.md.
Зачем WPF в 2026 году
WPF (Windows Presentation Foundation) — зрелый UI-фреймворк для настольных приложений Windows на .NET. Он остаётся стандартом там, где нужны:
- сложная вёрстка и кастомный дизайн без «веб в окне»;
- плотная интеграция с ОС (файлы, принтеры, Win32);
- привязка данных и MVVM «из коробки»;
- стабильный корпоративный стек на C#.
WPF рисует через DirectX (вектор, масштабирование на HiDPI). Альтернативы на Windows — WinForms (проще, но слабее по UI) и WinUI 3 (современный Fluent, другой API). Для учебного TaskDesk и типичного LOB-клиента WPF — практичный выбор: много материалов, Prism, богатые контролы.
Два языка одного приложения
| Слой | Язык | Файлы | Ответственность |
|---|---|---|---|
| Разметка | XAML | *.xaml | Дерево элементов, стили, привязки |
| Логика | C# | *.xaml.cs, ViewModel, сервисы | Поведение, данные, сеть |
XAML — декларативное описание объектного дерева UI. Компилятор превращает разметку в C#-инициализацию. Подробный синтаксис — в справочнике XAML.
Минимальное окно:
<Window x:Class="TaskDesk.Client.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TaskDesk" Height="480" Width="720">
<Grid Margin="16">
<TextBlock Text="Список задач" FontSize="20"/>
</Grid>
</Window>
Code-behind (MainWindow.xaml.cs) в MVVM-проекте обычно содержит только InitializeComponent().
Дерево элементов и layout
WPF строит UI как дерево зависимостей (DependencyObject). Корень — Window или UserControl; внутри — панели компоновки:
| Панель | Когда использовать |
|---|---|
| Grid | Табличная сетка, формы с подписями и полями |
| StackPanel | Вертикальный или горизонтальный список блоков |
| DockPanel | Панель инструментов, статус-бар |
| ScrollViewer | Прокрутка длинного содержимого |
Для TaskDesk типичная схема:
Window
└── Grid (2 строки)
├── Row 0: панель фильтров (StackPanel)
└── Row 1: ListBox с DataTemplate задач
Logical tree — структура XAML; visual tree — реальные визуальные примитивы (важно для стилей и ControlTemplate). В отладке помогает Live Visual Tree в Visual Studio.
Привязка данных — основа MVVM
Binding связывает свойство контрола со свойством ViewModel:
<TextBox Text="{Binding NewTitle, UpdateSourceTrigger=PropertyChanged}"/>
<ListBox ItemsSource="{Binding Tasks}" SelectedItem="{Binding SelectedTask}"/>
<Button Content="Добавить" Command="{Binding AddTaskCommand}"/>
| Режим | Смысл |
|---|---|
OneWay | ViewModel → UI (по умолчанию для многих свойств) |
TwoWay | Двусторонняя синхронизация (TextBox.Text) |
OneTime | Однократное чтение при загрузке |
ViewModel должна уведомлять UI об изменениях через INotifyPropertyChanged. Команды — через ICommand (кнопки без обработчиков Click в code-behind).
DataContext — «текущий объект для привязок». Его задают на Window или через DI в Prism (шаг 4).
Ресурсы, стили и шаблоны
| Механизм | Назначение |
|---|---|
| ResourceDictionary | Общие кисти, стили, конвертеры в App.xaml |
| Style | Набор Setter для типа (TextBox, Button) |
| DataTemplate | Как отображать один элемент данных в списке |
| ControlTemplate | Как выглядит сам контрол (форма кнопки, скругления) |
Централизация в App.xaml упрощает смену темы и согласованность TaskDesk с корпоративным брендом.
Жизненный цикл WPF-приложения
App.xaml— точка входа, глобальные ресурсы.- Создаётся главное окно (или Prism bootstrapper).
- UI-поток (Dispatcher) обрабатывает очередь сообщений Windows.
- Долгие операции (HTTP к API) — в фоне через
async/await; обновление коллекций в UI — на dispatcher-потоке.
Блокировка UI-потока синхронным HttpClient.GetStringAsync().Result — частая ошибка; в практикуме используем async команды (шаг 2).
Создание проекта для маршрута
dotnet new wpf -n TaskDesk.Client -o TaskDesk/src/TaskDesk.Client
cd TaskDesk/src/TaskDesk.Client
dotnet run
В .csproj должно быть <UseWPF>true</UseWPF>. Дальше по 119.md можно собрать локальный список; в шаге 2 вынесем логику в ViewModel, в шаге 4 подключим Prism.
Словарь терминов
| Термин | Простыми словами |
|---|---|
| DPI | Плотность пикселей; WPF использует device-independent units (1/96 дюйма) |
| DependencyProperty | Свойство с поддержкой привязок, анимаций, стилей |
| Markup Extension | {Binding}, {StaticResource} — расширения XAML |
| Code-behind | *.xaml.cs; в MVVM минимален |
| Dispatcher | Маршалинг вызовов в UI-поток |
Чек-лист шага 1
- Создан проект WPF, окно открывается на Windows.
- Понятно различие XAML (разметка) и C# (логика).
- Есть
GridилиStackPanelс хотя бы одной привязкой{Binding}. - Прочитан 119.md или повторены стили и
DataTemplate.
Дальше: Основы MVVM.
См. также
Другие статьи этого же раздела в боковом меню (как на странице "О разделе"). Model, View, ViewModel, INotifyPropertyChanged, ICommand, CommunityToolkit.Mvvm и тестируемая логика для TaskDesk. REST API для TaskDesk — контроллеры, DTO, Swagger, CORS, in-memory хранилище и контракт для WPF-клиента. Prism для WPF — модули, регионы, DI, INavigationService, HttpClient и ApiTaskRepository для TaskDesk.Client. Postman и Swagger для REST TaskDesk, WebApplicationFactory, xUnit, Moq для ViewModel и репозитория. Полноценное клиент-серверное приложение — solution, сборка, сценарии демо, расширения и чек-лист готовности.Практикум WPF — основы MVVM
Практикум WPF — сервер ASP.NET Core Web API
Практикум WPF — клиент на Prism
Практикум WPF — тестирование API и unit-тесты
Практикум WPF — итоговый проект TaskDesk