Учебник. Создание приложения WPF с помощью .NET
В этом руководстве описано, как использовать Visual Studio для создания нового приложения Windows Presentation Foundation (WPF). С помощью Visual Studio вы добавляете элементы управления в окна для проектирования пользовательского интерфейса приложения и обрабатываете входные события из этих элементов управления для взаимодействия с пользователем. К концу этого руководства у вас есть простое приложение, которое добавляет имена в поле списка.
Изучив это руководство, вы:
- Создайте новое приложение WPF.
- Добавление элементов управления в окно.
- Обработка событий элемента управления для предоставления функциональных возможностей приложения.
- Выполнить приложение.
Ниже приведена предварительная версия приложения, созданного в этом руководстве:
Необходимые компоненты
Внимание
.NET 6 больше не поддерживается. Рекомендуется использовать .NET 9.0.
- Visual Studio 2022 версии 17.0 или более поздней.
- Выберите рабочую нагрузку Разработка классических приложений .NET.
- Выберите отдельный компонент .NET 6.
Внимание
.NET 7 больше не поддерживается. Рекомендуется использовать .NET 9.0.
- Visual Studio 2022 версии 17.4 или более поздней версии
- Выберите рабочую нагрузку Разработка классических приложений .NET.
- Выберите отдельный компонент .NET 7
- Visual Studio 2022 версии 17.8 или более поздней версии
- Выберите рабочую нагрузку Разработка классических приложений .NET.
- Выберите отдельный компонент .NET 8
- Visual Studio 2022 версии 17.12 или более поздней версии
- Выберите рабочую нагрузку Разработка классических приложений .NET.
- Выберите отдельный компонент .NET 9
Создание приложения WPF
Первым шагом в создании нового приложения является запуск Visual Studio и создание приложения на основе шаблона.
Откройте Visual Studio.
Выберите Создать новый проект.
В поле Поиск шаблонов введите wpf и нажмите клавишу ВВОД.
В раскрывающемся списке язык кода выберите C# или Visual Basic.
В списке шаблонов выберите Приложение WPF, а затем нажмите Далее.
Внимание
Не выбирайте шаблон WPF Application (.NET Framework).
На следующем рисунке показаны шаблоны проектов как для C#, так и для Visual Basic .NET. Если вы применили фильтр языка кода, отображается только шаблон для этого языка.
В окне Настройка нового проекта выполните следующие действия:
- В поле Имя проекта введите Names.
- Установите флажок Разместить решение и проект в одном каталоге.
- При необходимости выберите другое расположение для сохранения кода.
- Нажмите кнопку Далее.
На странице Дополнительные сведения выберите .NET 6.0 (долгосрочная поддержка) в поле Требуемая версия .NET Framework. Выберите кнопку Создать.
Откройте Visual Studio.
Выберите Создать новый проект.
В поле Поиск шаблонов введите wpf и нажмите клавишу ВВОД.
В раскрывающемся списке язык кода выберите C# или Visual Basic.
В списке шаблонов выберите Приложение WPF, а затем нажмите Далее.
Внимание
Не выбирайте шаблон WPF Application (.NET Framework).
На следующем рисунке показаны шаблоны проектов как для C#, так и для Visual Basic .NET. Если вы применили фильтр языка кода, отображается только шаблон для этого языка.
В окне Настройка нового проекта выполните следующие действия:
- В поле Имя проекта введите Names.
- Установите флажок Разместить решение и проект в одном каталоге.
- При необходимости выберите другое расположение для сохранения кода.
- Нажмите кнопку Далее.
В окне дополнительных сведений выберите .NET 7.0 (стандартная поддержка терминов) для Target Framework. Выберите кнопку Создать.
Откройте Visual Studio.
Выберите Создать новый проект.
В поле Поиск шаблонов введите wpf и нажмите клавишу ВВОД.
В раскрывающемся списке язык кода выберите C# или Visual Basic.
В списке шаблонов выберите Приложение WPF, а затем нажмите Далее.
Внимание
Не выбирайте шаблон WPF Application (.NET Framework).
На следующем рисунке показаны шаблоны проектов как для C#, так и для Visual Basic .NET. Если вы применили фильтр языка кода, отображается только шаблон для этого языка.
В окне Настройка нового проекта выполните следующие действия:
- В поле Имя проекта введите Names.
- Установите флажок Разместить решение и проект в одном каталоге.
- При необходимости выберите другое расположение для сохранения кода.
- Нажмите кнопку Далее.
В окне "Дополнительные сведения" выберите .NET 8.0 (долгосрочная поддержка) для Целевой платформы. Выберите кнопку Создать.
Откройте Visual Studio.
Выберите Создать новый проект.
В поле Поиск шаблонов введите wpf и нажмите клавишу ВВОД.
В раскрывающемся списке язык кода выберите C# или Visual Basic.
В списке шаблонов выберите Приложение WPF, а затем нажмите Далее.
Внимание
Не выбирайте шаблон WPF Application (.NET Framework).
На следующем рисунке показаны шаблоны проектов как для C#, так и для Visual Basic .NET. Если вы применили фильтр языка кода, отображается только шаблон для этого языка.
В окне Настройка нового проекта выполните следующие действия:
- В поле Имя проекта введите Names.
- Установите флажок Разместить решение и проект в одном каталоге.
- При необходимости выберите другое расположение для сохранения кода.
- Нажмите кнопку Далее.
В окне "Дополнительные сведения" выберите .NET 9.0 (стандартная поддержка терминов) для Target Framework. Выберите кнопку Создать.
После создания приложения Visual Studio должен открыть окно конструктора XAML для окна по умолчанию MainWindow. Если конструктор не отображается, дважды щелкните файл MainWindow.xaml в окне Обозреватель решений, чтобы открыть конструктор.
Важные элементы среды Visual Studio
Поддержка WPF в Visual Studio содержит пять важных компонентов, с которыми вы взаимодействуете при создании приложения:
Обозреватель решений
Все файлы проекта, код, окна, ресурсы отображаются в этом окне.
Свойства
В этом окне показаны параметры свойств, которые можно настроить на основе выбранного элемента. Например, если выбрать элемент в Обозревателе решений, отобразятся параметры свойств, связанные с файлом. Если выбрать объект в конструкторе, вы увидите параметры элемента. Относительно предыдущего изображения в конструкторе выбрана строка заголовка окна.
Панель инструментов
Панель элементов содержит все элементы управления, которые можно добавить в область конструктора. Чтобы добавить элемент управления на текущую поверхность, дважды щелкните элемент управления или перетащите элемент управления на поверхности. Вместо этого используется окно редактора кода XAML для разработки пользовательского интерфейса при использовании окна конструктора XAML для предварительного просмотра результатов.
Конструктор XAML
Это конструктор для документа XAML. Он является интерактивным, и на него можно перетаскивать объекты из панели элементов. Выбрав и переместив элементы в конструкторе, вы можете визуально создавать пользовательский интерфейс для приложения.
Если конструктор и редактор отображаются, изменения в одном из них сразу отражаются в другом.
При выборе элементов в конструкторе окно "Свойства " отображает свойства и атрибуты этого объекта.
Редактор кода XAML
Это редактор кода XAML для документа XAML. Редактор кода XAML — это способ создания пользовательского интерфейса вручную без конструктора. Конструктор может автоматически задавать свойства элемента управления при добавлении элемента управления в конструктор. В редакторе кода XAML вам предоставляется гораздо больше контроля.
Если конструктор и редактор отображаются, изменения в одном из них сразу отражаются в другом. При навигации по тексту в редакторе кода окно свойств отображает свойства и атрибуты этого объекта.
Изучение кода XAML
После создания проекта в редакторе кода XAML отображается минимальный объем кода XAML для отображения окна. Если редактор не открыт, дважды щелкните элемент MainWindow.xaml в окне Обозреватель решений. Должен отобразиться код XAML, аналогичный следующему примеру:
<Window x:Class="Names.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Names"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
Внимание
Если вы кодируетсяе в Visual Basic, XAML немного отличается, в частности x:Class=".."
атрибут. XAML в Visual Basic использует имя класса объекта и исключает пространство имен для класса.
Чтобы лучше понять XAML, давайте разберем его. XAML — это просто XML, обрабатываемый WPF для создания пользовательского интерфейса. Для понимания XAML следует, как минимум, знать основы XML.
Корневой каталог <Window>
документа представляет тип объекта, описанного в XAML-файле. Объявлено восемь атрибутов, и обычно они относятся к трем категориям:
Пространства имен XML
Пространство имен XML предоставляет структуру языку XML, которая определяет содержимое, которое можно объявить в файле.
Основной атрибут
xmlns
импортирует пространство имен XML для всего файла, а в данном случае сопоставляется с типами, объявленными в WPF. Другие пространства имен XML объявляют префикс и импортируют другие типы и объекты для XAML-файла. Например, пространство именxmlns:local
объявляет префиксlocal
и выполняет сопоставление объектов, объявленных в проекте, с теми, которые объявлены в пространстве имен кодаNames
.Атрибут
x:Class
Этот атрибут сопоставляет
<Window>
тип, определенный кодом: файл MainWindow.xaml.cs или MainWindow.xaml.vb, который является классомNames.MainWindow
в C# иMainWindow
Visual Basic.Атрибут
Title
Любой обычный атрибут, объявленный в объекте XAML, задает свойство этого объекта. В этом случае атрибут
Title
задает свойствоWindow.Title
.
Изменение окна
Для нашего примера приложения это окно слишком велико, а его заголовок не является описательным. Давайте исправим это.
Сначала запустите приложение, нажав клавишу F5 или нажав кнопку "Начать отладку>" в меню.
Откроется окно по умолчанию, созданное шаблоном без элементов управления, и заголовок MainWindow:
Измените заголовок окна, задав для
Title
этого значениеNames
.Измените размер окна, задав
Width
для180
параметра иHeight
значение260
.<Window x:Class="Names.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Names" mc:Ignorable="d" Title="Names" Height="180" Width="260"> <Grid> </Grid> </Window>
Подготовка макета
В WPF имеется система макетов с широкими возможностями с множеством различных элементов управления макетом. Элементы управления макета помогают размещать дочерние элементы управления и изменять их размеры, а также могут даже это делать автоматически. Элемент управления макета по умолчанию, предоставляемый вам в этом XAML, — это элемент управления <Grid>
.
Элемент управления сеткой позволяет определять строки и столбцы, такие как таблица, и размещать элементы управления в границах определенной комбинации строк и столбцов. В сетку можно добавить любое количество дочерних элементов управления или другие элементы управления макетом. Например, можно разместить другой <Grid>
элемент управления в определенном сочетании строк и столбцов, а затем новая сетка может определить больше строк и столбцов и иметь собственные дочерние элементы.
Элемент управления сеткой помещает дочерние элементы управления в строки и столбцы. В сетке всегда объявлена одна строка и столбец, то есть сетка по умолчанию является отдельной ячейкой. Это не обеспечивает большую гибкость при размещении элементов управления.
Настройте макет сетки для элементов управления, необходимых для этого приложения.
Добавьте новый атрибут в
<Grid>
элемент:Margin="10"
Этот параметр приводит сетку из краев окна и делает его немного более хорошим.
Определите две строки и два столбца, разделив сетку на четыре ячейки:
<Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> </Grid>
Выберите сетку в редакторе кода XAML или в конструкторе XAML. Вы увидите, что в конструкторе XAML отображается каждая строка и столбец:
Добавление первого элемента управления
Теперь, когда сетка настроена, мы можем начать добавлять в нее элементы управления. Начните с элемента управления Label.
Создайте новый
<Label>
элемент внутри<Grid>
элемента после определений строк и столбцов. Задайте содержимое элемента строковым значениемNames
:<Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label>Names</Label> </Grid>
<Label>Names</Label>
определяет содержимоеNames
. Некоторым элементам управления известно, как управлять содержимым, а другим — нет. Содержимое элемента управления сопоставляется со свойствомContent
. При задании содержимого с помощью синтаксиса атрибутов XAML можно использовать следующий формат:<Label Content="Names" />
. Оба способа служат для выполнения одного и того же действия — отображение текстаNames
в качестве содержимого метки.Обратите внимание, что метка занимает половину окна, так как она была автоматически размещена на первой строке и столбце сетки. Для первой строки нам не нужно много пространства, поскольку мы будем использовать эту строку только для метки.
Измените атрибут
Height
первого параметра<RowDefinition>
с*
наAuto
.Значение
Auto
автоматически изменяет размер строки сетки под размер ее содержимого (в данном случае это элемент управления Label).<Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions>
Обратите внимание, что теперь в конструкторе отображается метка, занимающая небольшую часть доступной высоты. Теперь имеется больше места для следующей строки.
Размещение элементов управления
Давайте поговорим о размещении элементов управления. Метка, созданная в предыдущем разделе, автоматически помещается в строку 0 и столбец 0 сетки. Нумерирование строк и столбцов начинается с 0 и увеличивается на 1. Элементу управления ничего не известно о сетке, и элемент управления не определяет свойства для управления своим размещением в сетке.
Как указать элементу управления, что ему следует использовать другую строку или столбец, если элемент управления не имеет сведений о сетке? В этом случае на помощь придут вложенные свойства! Сетка использует эффективную систему свойств, предоставляемую WPF.
Элемент управления сеткой определяет новые свойства, которые дочерние элементы управления могут присоединять к себе. Свойства на самом деле не существуют в самом элементе управления, они доступны элементу управления после его добавления в сетку.
Сетка определяет два свойства для определения размещения строк и столбцов дочернего элемента управления: Grid.Row
и Grid.Column
. Если эти свойства опущены в элементе управления, предполагается, что они имеют значения по умолчанию 0, поэтому элемент управления помещается в строку 0
и столбец 0
сетки. Попробуйте изменить расположение элемента управления <Label>
, присвоив атрибуту Grid.Column
значение 1
:
<Label Grid.Column="1">Names</Label>
Обратите внимание, что метка перемещена во второй столбец. Вложенные свойства Grid.Row
и Grid.Column
можно использовать для размещения последующих элементов управления, которые мы создадим. Но теперь восстановите метку до столбца 0.
Создание поля со списком имен
Теперь, когда сетка имеет правильный размер и создана метка, добавьте элемент управления "Список" в строку под меткой.
Объявите
<ListBox />
элемент управления под элементом<Label>
управления.Установите свойство
Grid.Row
в значение1
.Установите свойство
x:Name
в значениеlstNames
.После присвоения имени элементу управления на него можно ссылаться в коде. Имя присваивается элементу управления с помощью атрибута
x:Name
.
Вот как должен выглядеть XAML:
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label>Names</Label>
<ListBox Grid.Row="1" x:Name="lstNames" />
</Grid>
Добавление оставшихся элементов управления
Последние два элемента управления, которые мы добавим, — это текстовое поле и кнопка, которую пользователь использует для ввода имени для добавления в поле списка. Однако вместо того, чтобы создать дополнительные строки и столбцы в сетке для упорядочивания этих элементов управления, мы поместим эти элементы управления в элемент управления макета <StackPanel>
.
Панель стека отличается от сетки тем, как в ней размещаются элементы управления. Хотя вы сообщаете сетке, где нужно, чтобы элементы управления были с Grid.Row
свойствами и Grid.Column
присоединенными свойствами, панель стека будет автоматически выкладывать каждую из дочерних элементов управления последовательно. Он "стекает" каждый элемент управления после другого.
Объявите
<StackPanel>
элемент управления под элементом<ListBox>
управления.Установите свойство
Grid.Row
в значение1
.Установите свойство
Grid.Column
в значение1
.Задайте для
Margin
значение5,0,0,0
.<Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label>Names</Label> <ListBox Grid.Row="1" x:Name="lstNames" /> <StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0"> </StackPanel>
Атрибут
Margin
ранее уже использовался в сетке, однако теперь мы поместим только одно значение,10
. Это поле имеет значение5,0,0,0
, которое очень отличается от10
. Свойство поля является типомThickness
и может интерпретировать оба значения. Толщина определяет пространство вокруг каждой стороны прямоугольника, слева, сверху, справа, снизу, соответственно. Если значение поля является одним значением, оно используется для всех четырех сторон.В элементе
<StackPanel>
управления создайте<TextBox />
элемент управления.- Установите свойство
x:Name
в значениеtxtName
.
- Установите свойство
Наконец, после
<TextBox>
того, как элемент управления еще находится внутри<StackPanel>
элемента управления, создайте<Button>
элемент управления.- Установите свойство
x:Name
в значениеbtnAdd
. - Задайте для
Margin
значение0,5,0,0
. - Задайте для
Add Name
содержимого значение .
- Установите свойство
Вот как должен выглядеть XAML:
<StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0">
<TextBox x:Name="txtName" />
<Button x:Name="btnAdd" Margin="0,5,0,0">Add Name</Button>
</StackPanel>
Макет окна готов. Однако в наше приложение следует добавить логику, чтобы оно работало. Далее необходимо подключить события элемента управления к коду, чтобы приложение выполняло действия.
Добавление кода для события Click
Созданная нами кнопка <Button>
имеет событие Click
, возникающее, когда пользователь нажимает кнопку. Можно подписаться на это событие и добавить код, который будет добавлять имя в список. Атрибуты XAML используются для подписки на события так же, как они используются для задания свойств.
<Button>
Найдите элемент управления.Задайте для атрибута
Click
значениеButtonAddName_Click
.<StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0"> <TextBox x:Name="txtName" /> <Button x:Name="btnAdd" Margin="0,5,0,0" Click="ButtonAddName_Click">Add Name</Button> </StackPanel>
Создайте код обработчика событий. Щелкните правой кнопкой мыши
ButtonAddName_Click
и выберите Перейдите к определению.Это действие создает метод в коде позади, который соответствует указанному имени обработчика.
private void ButtonAddName_Click(object sender, RoutedEventArgs e) { }
Private Sub ButtonAddName_Click(sender As Object, e As RoutedEventArgs) End Sub
Затем добавьте следующий код для выполнения следующих трех шагов:
- Проверка того, что в текстовом поле содержится имя.
- Проверка того, что имя, указанное в текстовом поле, еще не добавлено.
- Добавление имени в список.
private void ButtonAddName_Click(object sender, RoutedEventArgs e) { if (!string.IsNullOrWhiteSpace(txtName.Text) && !lstNames.Items.Contains(txtName.Text)) { lstNames.Items.Add(txtName.Text); txtName.Clear(); } }
Private Sub ButtonAddName_Click(sender As Object, e As RoutedEventArgs) If Not String.IsNullOrWhiteSpace(txtName.Text) And Not lstNames.Items.Contains(txtName.Text) Then lstNames.Items.Add(txtName.Text) txtName.Clear() End If End Sub
Выполнить приложение
Теперь, когда событие обрабатывается, запустите приложение. Отобразится окно, и вы можете ввести имя в текстовое поле, а затем добавить его, нажав кнопку.
Связанный контент
.NET Desktop feedback