Поделиться через


Учебник. Создание приложения WPF с помощью .NET

В этом руководстве описано, как использовать Visual Studio для создания нового приложения Windows Presentation Foundation (WPF). С помощью Visual Studio вы добавляете элементы управления в окна для проектирования пользовательского интерфейса приложения и обрабатываете входные события из этих элементов управления для взаимодействия с пользователем. К концу этого руководства у вас есть простое приложение, которое добавляет имена в поле списка.

Изучив это руководство, вы:

  • Создайте новое приложение WPF.
  • Добавление элементов управления в окно.
  • Обработка событий элемента управления для предоставления функциональных возможностей приложения.
  • Выполнить приложение.

Ниже приведена предварительная версия приложения, созданного в этом руководстве:

Готовый пример приложения WPF

Необходимые компоненты

Внимание

.NET 6 больше не поддерживается. Рекомендуется использовать .NET 9.0.

Внимание

.NET 7 больше не поддерживается. Рекомендуется использовать .NET 9.0.

Создание приложения WPF

Первым шагом в создании нового приложения является запуск Visual Studio и создание приложения на основе шаблона.

  1. Откройте Visual Studio.

  2. Выберите Создать новый проект.

    Создайте проект WPF в Visual Studio 2022 для .NET. 6

  3. В поле Поиск шаблонов введите wpf и нажмите клавишу ВВОД.

  4. В раскрывающемся списке язык кода выберите C# или Visual Basic.

  5. В списке шаблонов выберите Приложение WPF, а затем нажмите Далее.

    Внимание

    Не выбирайте шаблон WPF Application (.NET Framework).

    На следующем рисунке показаны шаблоны проектов как для C#, так и для Visual Basic .NET. Если вы применили фильтр языка кода, отображается только шаблон для этого языка.

    Найдите шаблон WPF в Visual Studio 2022 для .NET. 6

  6. В окне Настройка нового проекта выполните следующие действия:

    1. В поле Имя проекта введите Names.
    2. Установите флажок Разместить решение и проект в одном каталоге.
    3. При необходимости выберите другое расположение для сохранения кода.
    4. Нажмите кнопку Далее.

    Настройка нового проекта WPF в Visual Studio 2022 для .NET 6

  7. На странице Дополнительные сведения выберите .NET 6.0 (долгосрочная поддержка) в поле Требуемая версия .NET Framework. Выберите кнопку Создать.

    Выбор целевой платформы для нового проекта WPF в Visual Studio 2022 для .NET 6

  1. Откройте Visual Studio.

  2. Выберите Создать новый проект.

    Создайте проект WPF в Visual Studio 2022 для .NET 7.

  3. В поле Поиск шаблонов введите wpf и нажмите клавишу ВВОД.

  4. В раскрывающемся списке язык кода выберите C# или Visual Basic.

  5. В списке шаблонов выберите Приложение WPF, а затем нажмите Далее.

    Внимание

    Не выбирайте шаблон WPF Application (.NET Framework).

    На следующем рисунке показаны шаблоны проектов как для C#, так и для Visual Basic .NET. Если вы применили фильтр языка кода, отображается только шаблон для этого языка.

    Найдите шаблон WPF в Visual Studio 2022 для .NET. 7

  6. В окне Настройка нового проекта выполните следующие действия:

    1. В поле Имя проекта введите Names.
    2. Установите флажок Разместить решение и проект в одном каталоге.
    3. При необходимости выберите другое расположение для сохранения кода.
    4. Нажмите кнопку Далее.

    Настройка нового проекта WPF в Visual Studio 2022 для .NET 7

  7. В окне дополнительных сведений выберите .NET 7.0 (стандартная поддержка терминов) для Target Framework. Выберите кнопку Создать.

    Выбор целевой платформы для нового проекта WPF в Visual Studio 2022 для .NET 7

  1. Откройте Visual Studio.

  2. Выберите Создать новый проект.

    Снимок экрана: диалоговое окно запуска из Visual Studio 2022. Кнопка

  3. В поле Поиск шаблонов введите wpf и нажмите клавишу ВВОД.

  4. В раскрывающемся списке язык кода выберите C# или Visual Basic.

  5. В списке шаблонов выберите Приложение WPF, а затем нажмите Далее.

    Внимание

    Не выбирайте шаблон WPF Application (.NET Framework).

    На следующем рисунке показаны шаблоны проектов как для C#, так и для Visual Basic .NET. Если вы применили фильтр языка кода, отображается только шаблон для этого языка.

    Термин wpf находится в поле поиска и выделен красной стрелкой. Два шаблона в списке результатов выделены красными полями, C# и Visual Basic. Кнопка

  6. В окне Настройка нового проекта выполните следующие действия:

    1. В поле Имя проекта введите Names.
    2. Установите флажок Разместить решение и проект в одном каталоге.
    3. При необходимости выберите другое расположение для сохранения кода.
    4. Нажмите кнопку Далее.

    Снимок экрана: диалоговое окно

  7. В окне "Дополнительные сведения" выберите .NET 8.0 (долгосрочная поддержка) для Целевой платформы. Выберите кнопку Создать.

    Снимок экрана: диалоговое окно

  1. Откройте Visual Studio.

  2. Выберите Создать новый проект.

    Снимок экрана: диалоговое окно запуска из Visual Studio 2022. Кнопка

  3. В поле Поиск шаблонов введите wpf и нажмите клавишу ВВОД.

  4. В раскрывающемся списке язык кода выберите C# или Visual Basic.

  5. В списке шаблонов выберите Приложение WPF, а затем нажмите Далее.

    Внимание

    Не выбирайте шаблон WPF Application (.NET Framework).

    На следующем рисунке показаны шаблоны проектов как для C#, так и для Visual Basic .NET. Если вы применили фильтр языка кода, отображается только шаблон для этого языка.

    Термин wpf находится в поле поиска и выделен красной стрелкой. Два шаблона в списке результатов выделены красными полями, C# и Visual Basic. Кнопка

  6. В окне Настройка нового проекта выполните следующие действия:

    1. В поле Имя проекта введите Names.
    2. Установите флажок Разместить решение и проект в одном каталоге.
    3. При необходимости выберите другое расположение для сохранения кода.
    4. Нажмите кнопку Далее.

    Снимок экрана: диалоговое окно

  7. В окне "Дополнительные сведения" выберите .NET 9.0 (стандартная поддержка терминов) для Target Framework. Выберите кнопку Создать.

    Снимок экрана: диалоговое окно

После создания приложения Visual Studio должен открыть окно конструктора XAML для окна по умолчанию MainWindow. Если конструктор не отображается, дважды щелкните файл MainWindow.xaml в окне Обозреватель решений, чтобы открыть конструктор.

Важные элементы среды Visual Studio

Поддержка WPF в Visual Studio содержит пять важных компонентов, с которыми вы взаимодействуете при создании приложения:

Важные компоненты Visual Studio, о которых нужно знать при создании проекта WPF для .NET

  1. Обозреватель решений

    Все файлы проекта, код, окна, ресурсы отображаются в этом окне.

  2. Свойства

    В этом окне показаны параметры свойств, которые можно настроить на основе выбранного элемента. Например, если выбрать элемент в Обозревателе решений, отобразятся параметры свойств, связанные с файлом. Если выбрать объект в конструкторе, вы увидите параметры элемента. Относительно предыдущего изображения в конструкторе выбрана строка заголовка окна.

  3. Панель инструментов

    Панель элементов содержит все элементы управления, которые можно добавить в область конструктора. Чтобы добавить элемент управления на текущую поверхность, дважды щелкните элемент управления или перетащите элемент управления на поверхности. Вместо этого используется окно редактора кода XAML для разработки пользовательского интерфейса при использовании окна конструктора XAML для предварительного просмотра результатов.

  4. Конструктор XAML

    Это конструктор для документа XAML. Он является интерактивным, и на него можно перетаскивать объекты из панели элементов. Выбрав и переместив элементы в конструкторе, вы можете визуально создавать пользовательский интерфейс для приложения.

    Если конструктор и редактор отображаются, изменения в одном из них сразу отражаются в другом.

    При выборе элементов в конструкторе окно "Свойства " отображает свойства и атрибуты этого объекта.

  5. Редактор кода 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.

Изменение окна

Для нашего примера приложения это окно слишком велико, а его заголовок не является описательным. Давайте исправим это.

  1. Сначала запустите приложение, нажав клавишу F5 или нажав кнопку "Начать отладку>" в меню.

    Откроется окно по умолчанию, созданное шаблоном без элементов управления, и заголовок MainWindow:

    Пустое приложение WPF

  2. Измените заголовок окна, задав для Title этого значение Names.

  3. Измените размер окна, задав 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> элемент управления в определенном сочетании строк и столбцов, а затем новая сетка может определить больше строк и столбцов и иметь собственные дочерние элементы.

Элемент управления сеткой помещает дочерние элементы управления в строки и столбцы. В сетке всегда объявлена одна строка и столбец, то есть сетка по умолчанию является отдельной ячейкой. Это не обеспечивает большую гибкость при размещении элементов управления.

Настройте макет сетки для элементов управления, необходимых для этого приложения.

  1. Добавьте новый атрибут в <Grid> элемент: Margin="10"

    Этот параметр приводит сетку из краев окна и делает его немного более хорошим.

  2. Определите две строки и два столбца, разделив сетку на четыре ячейки:

    <Grid Margin="10">
        
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
    
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        
    </Grid>
    
  3. Выберите сетку в редакторе кода XAML или в конструкторе XAML. Вы увидите, что в конструкторе XAML отображается каждая строка и столбец:

    Приложение WPF с полями, заданными для сетки

Добавление первого элемента управления

Теперь, когда сетка настроена, мы можем начать добавлять в нее элементы управления. Начните с элемента управления Label.

  1. Создайте новый <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 в качестве содержимого метки.

    Обратите внимание, что метка занимает половину окна, так как она была автоматически размещена на первой строке и столбце сетки. Для первой строки нам не нужно много пространства, поскольку мы будем использовать эту строку только для метки.

  2. Измените атрибут Height первого параметра <RowDefinition> с * на Auto.

    Значение Auto автоматически изменяет размер строки сетки под размер ее содержимого (в данном случае это элемент управления Label).

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    

    Обратите внимание, что теперь в конструкторе отображается метка, занимающая небольшую часть доступной высоты. Теперь имеется больше места для следующей строки.

    Приложение WPF с полями, заданными для сетки, и элементом управления Label в первой строке

Размещение элементов управления

Давайте поговорим о размещении элементов управления. Метка, созданная в предыдущем разделе, автоматически помещается в строку 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.

Создание поля со списком имен

Теперь, когда сетка имеет правильный размер и создана метка, добавьте элемент управления "Список" в строку под меткой.

  1. Объявите <ListBox /> элемент управления под элементом <Label> управления.

  2. Установите свойство Grid.Row в значение 1.

  3. Установите свойство 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 присоединенными свойствами, панель стека будет автоматически выкладывать каждую из дочерних элементов управления последовательно. Он "стекает" каждый элемент управления после другого.

  1. Объявите <StackPanel> элемент управления под элементом <ListBox> управления.

  2. Установите свойство Grid.Row в значение 1.

  3. Установите свойство Grid.Column в значение 1.

  4. Задайте для 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 и может интерпретировать оба значения. Толщина определяет пространство вокруг каждой стороны прямоугольника, слева, сверху, справа, снизу, соответственно. Если значение поля является одним значением, оно используется для всех четырех сторон.

  5. В элементе <StackPanel> управления создайте <TextBox /> элемент управления.

    1. Установите свойство x:Name в значение txtName.
  6. Наконец, после <TextBox>того, как элемент управления еще находится внутри <StackPanel>элемента управления, создайте <Button> элемент управления.

    1. Установите свойство x:Name в значение btnAdd.
    2. Задайте для Margin значение 0,5,0,0.
    3. Задайте для 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 используются для подписки на события так же, как они используются для задания свойств.

  1. <Button> Найдите элемент управления.

  2. Задайте для атрибута 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>
    
  3. Создайте код обработчика событий. Щелкните правой кнопкой мыши ButtonAddName_Click и выберите Перейдите к определению.

    Это действие создает метод в коде позади, который соответствует указанному имени обработчика.

    private void ButtonAddName_Click(object sender, RoutedEventArgs e)
    {
    
    }
    
    Private Sub ButtonAddName_Click(sender As Object, e As RoutedEventArgs)
    
    End Sub
    
  4. Затем добавьте следующий код для выполнения следующих трех шагов:

    1. Проверка того, что в текстовом поле содержится имя.
    2. Проверка того, что имя, указанное в текстовом поле, еще не добавлено.
    3. Добавление имени в список.
    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
    

Выполнить приложение

Теперь, когда событие обрабатывается, запустите приложение. Отобразится окно, и вы можете ввести имя в текстовое поле, а затем добавить его, нажав кнопку.

Запуск приложения Windows Presentation Foundation (WPF) для .NET.