Как установить wpf в visual studio
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Учебник. Создание приложения WPF с помощью Visual Basic
Выполняя действия из этого учебника, вы создадите приложение на Visual Basic в интегрированной среде разработки (IDE) Visual Studio. Ваша программа будет использовать платформу пользовательского интерфейса Windows Presentation Foundation (WPF). При выполнении действий из этого учебника вы ознакомитесь со многими инструментами, диалоговыми окнами и конструкторами, которые можно использовать в Visual Studio.
В этом руководстве описано следующее:
- Создание проекта
- Настройка окна и добавление текста
- Добавление кнопок и кода
- Отладка и тестирование приложения
- Отладка с точками останова
- Сборка версии в режиме выпуска
. moniker range="vs-2017" Для выполнения шагов, описанных в этом учебнике, вам понадобится Visual Studio. Перейдите на страницу загрузки Visual Studio, чтобы получить бесплатную версию. . moniker-end . moniker range="vs-2019" Для выполнения шагов, описанных в этом учебнике, вам понадобится Visual Studio. Перейдите на страницу загрузки Visual Studio, чтобы получить бесплатную версию. . moniker-end . moniker range=">=vs-2022" Для выполнения шагов, описанных в этом учебнике, вам понадобится Visual Studio. Перейдите на страницу загрузки Visual Studio, чтобы получить бесплатную версию. . moniker-end
При создании приложения в Visual Studio необходимо сначала создать проект. Для целей этого учебника создайте проект Windows Presentation Foundation.
Запустите Visual Studio.
В строке меню выберите Файл > Создать > Проект.
Visual Studio создает проект и решение HelloWPFApp. А в Обозревателе решений отображаются различные файлы.
Конструктор WPF отображает представление кода и представление XAML MainWindow.xaml в представлении с разделением. . moniker-end . moniker range="vs-2019"
Запустите Visual Studio.
Присвойте проекту имя HelloWPFApp и щелкните Создать.
Visual Studio создает проект и решение HelloWPFApp. А в Обозревателе решений отображаются различные файлы.
Конструктор WPF отображает представление кода и представление XAML MainWindow.xaml в представлении с разделением. . moniker-end
Запустите Visual Studio.
На начальном экране выберите Создать проект.
. image type="content" source="media/vs-2022/start-window-create-new-project.jpg" alt-text="Снимок экрана: окно запуска в Visual Studio 2022, выделен вариант "Создать проект".".
. image type="content" source="media/tutorial-wpf/visual-studio-create-wpf-project.jpg" alt-text="Снимок экрана: диалоговое окно "Создать проект", в поле поиска введено "WPF", выбран "Visual Basic" в списке языков, выделен шаблон проекта "Приложение WPF (.NET Framework)"".
Присвойте проекту имя HelloWPFApp и щелкните Создать.
Visual Studio создает проект и решение HelloWPFApp. А в Обозревателе решений отображаются различные файлы.
. image type="content" source="media/vs-2022/explore-ide-hello-wpf-app-files.jpg" alt-text="Снимок экрана: файлы в проекте HelloWPFApp и решение в Обозревателе решений".
Конструктор WPF отображает представление кода и представление XAML MainWindow.xaml в представлении с разделением. . moniker-end
[!NOTE] Дополнительные сведения о eXtensible Application Markup Language (XAML) см. в обзоре XAML для WPF.
Настройка окна и добавление текста
С помощью окна Свойства можно отображать и изменять параметры элементов проекта, элементов управления и других элементов.
В Обозревателе решений откройте файл MainWindow.xaml .
В представлении XAML измените значение свойства Window.Title с Title="MainWindow" на Title="Greetings" .
В левой части интегрированной среды разработки Visual Studio выберите вкладку Панель элементов. Если вы ее не видите, выберите пункт Представление > Панель элементов в строке меню или воспользуйтесь комбинацией клавиш Ctrl+Alt+X.
Разверните категорию Типовые элементы управления WPF или введите Text в строке поиска, чтобы найти TextBlock.
. image type="content" source="media/tutorial-wpf/toolbox-tab-text-block.jpg" alt-text="Снимок экрана: окно панели элементов с элементом управления TextBlock, выделенным в списке распространенных элементов управления WPF".
Выберите элемент TextBlock и перетащите его в окно в области конструктора. Элемент управления TextBlock можно переместить, перетащив его. Ориентируйтесь на рекомендации, чтобы разместить элемент управления.
. image type="content" source="media/tutorial-wpf/form-with-text-block.jpg" alt-text="Снимок экрана: элемент управления TextBlock в форме приветствия с направляющими".
Разметка XAML должна выглядеть так, как в следующем примере:
В представлении XAML найдите разметку для TextBlock и измените атрибут Text:
При необходимости отцентрируйте TextBlock еще раз
Сохраните приложение, нажав кнопку Сохранить все на панели инструментов. Кроме того, чтобы сохранить приложение, в строке меню можно выбрать пункт Файл > Сохранить все (или нажать клавиши Ctrl+Shift+S). Рекомендуется выполнять сохранение от начала разработки и как можно чаще.
Добавление кнопок и кода
Приложение использует два переключателя и кнопку. Чтобы добавить их, выполните следующие действия. Вы добавите код Visual Basic для кнопки. Этот код относится к выбору переключателя.
На панели элементов найдите RadioButton.
. image type="content" source="media/tutorial-wpf/toolbox-radio-button.jpg" alt-text="Снимок экрана: окно панели элементов с элементом управления RadioButton, выбранным в списке распространенных элементов управления WPF".
Добавьте два элемента управления RadioButton в область конструктора, выбрав элемент RadioButton и перетащив его в область конструктора. Переместите кнопки, выбрав их и используя клавиши со стрелками. Разместите кнопки параллельно под элементом управления TextBlock.
. image type="content" source="media/tutorial-wpf/greetings-form-radio-buttons.jpg" alt-text="Снимок экрана: форма приветствия с элементом управления TextBlock и двумя переключателями".
В окне Свойства для левого элемента управления RadioButton измените свойство Name в верхней части окна Свойства, присвоив ему значение HelloButton.
. image type="content" source="media/tutorial-wpf/properties-radio-button-name.jpg" alt-text="Снимок экрана: окно свойств Обозревателя решений для переключателя HelloButton".
В окне Свойства правого элемента управления RadioButton измените значение свойства Name на GoodbyeButton.
Измените атрибут Content для кнопок HelloButton и GoodbyeButton на "Hello" и "Goodbye" в XAML.
В представлении XAML найдите разметку для элемента HelloButton и добавьте атрибут IsChecked:
Атрибут IsChecked со значением True означает, что HelloButton задается по умолчанию. Этот параметр означает, что переключатель будет выбран всегда, даже при запуске программы.
На панели элементов найдите элемент управления Button, а затем перетащите кнопку в область конструктора, под элементами управления RadioButton.
В представлении XAML измените значение свойства Content элемента управления Button с Content="Button" на Content="Display" .
Окно должно выглядеть так, как показано на следующем рисунке.
. image type="content" source="media/tutorial-wpf/greetings-buttons.jpg" alt-text="Снимок экрана: форма приветствия с элементом управления TextBlock, переключателями с метками Hello и Goodbye, а также элементом управления "Кнопка" с меткой Display".
На поверхности разработки дважды щелкните кнопку Display .
Будет открыт файл Greetings.xaml.vb, а курсор установлен на событии Button_Click .
Добавьте следующий код:
Отладка и тестирование приложения
В обозревателе решений щелкните правой кнопкой мыши файл MainWindow.xaml и выберите команду Переименовать. Измените имя файла на Greetings.xaml.
Запустите отладчик, нажав клавишу F5 или выбрав пункты меню Отладка и Начать отладку.
Появится окно Режим приостановки выполнения, а в окне Вывод будет указано, что произошло исключение.
Остановите отладчик, выбрав в меню Отладка > Остановить отладку.
В начале этого раздела вы переименовали файл MainWindow.xaml в файл Greetings.xaml. Однако код по-прежнему ссылается на файл MainWindow.xaml как на URI запуска приложения, поэтому проект не удается запустить.
В обозревателе решений откройте файл Application.xaml.
Измените StartupUri="MainWindow.xaml" на StartupUri="Greetings.xaml" .
Запустите отладчик снова (клавишей F5). Должно появиться окно приветствия приложения.
. image type="content" source="media/vs-2022/explore-ide-wpf-running-app.jpg" alt-text="Снимок экрана: окно приветствия с видимыми элементами управления TextBlock, RadioButton и Button. Выбран переключатель Hello".
Выберите кнопку Hello и Display, а затем Goodbye и Display. Чтобы завершить отладку, щелкните значок "Закрыть" в правом верхнем углу.
Дополнительные сведения см. в разделе Построение приложения WPF и статье Отладка WPF.
Отладка с точками останова
Добавив точки останова, можно тестировать код во время отладки.
Откройте файл Greetings.xaml.vb и выделите строку MessageBox.Show("Hello.") .
Добавьте точку останова, нажав клавишу F9 или выбрав пункт Отладка, а затем — Точка останова.
Рядом со строкой кода в левом поле окна редактора появится красный кружок.
Выделите следующую строку: MessageBox.Show("Goodbye.") .
Нажмите клавишу F9, чтобы добавить точку останова, а затем нажмите клавишу F5, чтобы начать отладку.
В окне Greetings нажмите кнопку Hello, а затем — Display.
Строка MessageBox.Show("Hello.") выделяется желтым цветом. В нижней части интегрированной среды разработки окна Видимые, Локальные и Контрольные значения соединены с левой стороны. А окна Стек вызовов, Точки останова, Параметры исключений, Команда, Интерпретация и Вывод — с правой.
. image type="content" source="media/vs-2022/explore-ide-debug-breakpoint.jpg" alt-text="Снимок экрана: сеанс отладки в Visual Studio с открытыми окнами "Код", "Диагностика", "Видимые" и "Стек вызовов". Выполнение остановлено в точке останова Greetings.xaml.vb".
В строке меню выберите Отладка > Шаг с выходом.
Приложение запустится снова. Появится диалоговое окно со словом Hello.
В окне Greetings выберите переключатель Goodbye и нажмите кнопку Display .
Строка MessageBox.Show("Goodbye.") выделяется желтым цветом.
Нажмите клавишу F5, чтобы продолжить отладку. Когда откроется диалоговое окно, нажмите кнопку ОК, чтобы закрыть его.
Закройте окно приложения, чтобы остановить отладку.
В строке меню выберите Отладка > Выключить все точки останова.
Сборка версии в режиме выпуска
Теперь, когда вы проверили, что все работает, можно подготовить окончательную сборку приложения.
Выберите пункты Сборка и > Очистить решение для удаления промежуточных файлов и выходных файлов, которые были созданы в ходе предыдущих сборок.
Измените конфигурацию сборки для HelloWPFApp с Отладка на Выпуск с помощью раскрывающегося списка на панели инструментов.
Выберите Сборка > Собрать решение.
Поздравляем с завершением этого учебника! Построенный файл .exe находится в каталоге решения и проекта ( . \HelloWPFApp\HelloWPFApp\bin\Release).
Перейдите к следующей статье, чтобы ознакомиться с инструкциями по созданию приложения Windows Forms на Visual Basic в Visual Studio.
Из этого краткого руководства вы узнаете, как создать приложение Windows Presentation Foundation (WPF) с помощью Visual Studio. После создания первоначального приложения вы научитесь добавлять элементы управления и обрабатывать события. По завершении работы с этим руководством у вас будет простое приложение, добавляющее имена в список.
В этом руководстве описано следующее:
- Создание приложения WPF
- Добавление элементов управления на форму
- Обработка событий элемента управления для предоставления функциональных возможностей приложения
- Запустите приложение
Ниже представлен предварительный просмотр приложения, которое будет создано в данном руководстве.
Предварительные требования
Создание приложения WPF
Первым шагом в создании нового приложения является запуск Visual Studio и создание приложения на основе шаблона.
Запустите Visual Studio.
Выберите Создать новый проект.
В поле Поиск шаблонов введите wpf и нажмите клавишу ВВОД .
В списке шаблонов выберите Приложение WPF, а затем нажмите Далее.
В окне Настройка нового проекта выполните следующие действия:
Запустите Visual Studio.
Выберите Создать новый проект.
В поле Поиск шаблонов введите wpf и нажмите клавишу ВВОД .
В списке шаблонов выберите Приложение WPF, а затем нажмите Далее.
В окне Настройка нового проекта выполните следующие действия:
После создания приложения в Visual Studio должна открыться панель конструктора XAML для формы по умолчанию MainWindow. Если конструктор не отображается, дважды щелкните файл MainWindow.xaml в области Обозреватель решений, чтобы открыть конструктор.
Важные элементы среды Visual Studio
Поддержка WPF в Visual Studio состоит из пяти важных компонентов, с которыми вы будете взаимодействовать при создании приложения.
Все файлы проекта, код, окна и ресурсы отображаются в этой области.
На этой панели отображаются параметры свойств, которые можно настроить в зависимости от выбранного элемента. Например, если выбрать элемент в Обозревателе решений, отобразятся параметры свойств, связанные с файлом. Если выбрать объект в конструкторе, отобразятся параметры этого элемента.
Панель элементов содержит все элементы управления, которые можно добавить на форму. Чтобы добавить элемент управления на текущую форму, дважды щелкните элемент управления или перетащите его.
Это конструктор для документа XAML. Он является интерактивным, и на него можно перетаскивать объекты из панели элементов. Выбирая и перемещая элементы в конструкторе, можно визуально создавать пользовательский интерфейс для приложения.
Если конструктор и редактор отображаются, изменения в одном из них сразу отражаются в другом. При выборе элементов в конструкторе в области Свойства отображаются свойства и атрибуты этого объекта.
Редактор кода XAML
Это редактор кода XAML для документа XAML. Редактор кода XAML — это способ создания пользовательского интерфейса вручную без конструктора. Конструктор может вычислять значения свойств элемента управления при его добавлении в конструктор. В редакторе кода XAML вам предоставляется гораздо больше контроля.
Если конструктор и редактор отображаются, изменения в одном из них сразу отражаются в другом. При переходе по текстовым курсорам в редакторе кода в области Свойства отображаются свойства и атрибуты этого объекта.
Изучение кода XAML
После создания проекта в редакторе кода XAML отображается минимальный объем кода XAML для отображения окна. Если редактор не открыт, дважды щелкните элемент MainWindow.xaml в обозревателе решений. Вы должны увидеть XAML, аналогичный приведенному ниже примеру.
Корень документа представляет тип объекта, описываемого файлом XAML. Объявлено восемь атрибутов, и обычно они относятся к трем категориям:
Пространство имен XML предоставляет структуру XML, определяя, какое содержимое XML может быть объявлено в файле.
Основной атрибут xmlns импортирует пространство имен XML для всего файла, а в данном случае сопоставляется с типами, объявленными в WPF. Другие пространства имен XML объявляют префикс и импортируют другие типы и объекты для XAML-файла. Например, пространство имен xmlns:local объявляет префикс local и выполняет сопоставление объектов, объявленных в проекте, с теми, которые объявлены в пространстве имен кода Names .
Этот атрибут сопоставляет с типом, определенным в коде: файл MainWindow.xaml.cs или MainWindow.xaml.vb, который является классом Names.MainWindow .
Любой обычный атрибут, объявленный в объекте XAML, задает свойство этого объекта. В этом случае Title атрибут задает Window.Title свойство.
Изменение окна
Сначала запустите проект и просмотрите выходные данные по умолчанию. Вы увидите окно, которое появляется, без элементов управления, и заголовок MainWindow:
Для нашего примера приложения это окно слишком велико, а его заголовок не является описательным. Измените заголовок и размер окна, заменив соответствующие атрибуты в XAML следующими значениями:
Подготовка макета
В WPF имеется система макетов с широкими возможностями с множеством различных элементов управления макетом. Элементы управления макета помогают размещать дочерние элементы управления и изменять их размеры, а также могут даже это делать автоматически. Элемент управления макета по умолчанию, предоставляемый вам в этом XAML, — это элемент управления .
Элемент управления Grid позволяет определить строки и столбцы, почти как в таблице, и размещать элементы управления внутри границ определенной комбинации строк и столбцов. Можно добавить любое количество дочерних элементов управления или других элементов управления макетом, имеющихся в Grid . Например, другой элемент управления Grid можно поместить в определенную комбинацию строк и столбцов, а для этого нового Grid затем можно задать больше строк и столбцов и собственные дочерние элементы.
Элемент управления определяет строки и столбцы, в которых будут находиться элементы управления. В сетке всегда объявлена одна строка и столбец, то есть сетка по умолчанию является отдельной ячейкой. Это не обеспечивает большую гибкость при размещении элементов управления.
Прежде чем добавлять новые строки и столбцы, добавьте новый атрибут в элемент : Margin="10" . Будет вставлена сетка, благодаря чему окно будет выглядеть немного лучше.
Затем определите две строки и два столбца, разделив сетку на четыре ячейки:
Выберите сетку в редакторе кода XAML или в конструкторе XAML. Вы увидите, что в конструкторе XAML отображается каждая строка и столбец:
Добавление первого элемента управления
После создания сетки можно приступать к добавлению в нее элементов управления. Начните с элемента управления Label. Создайте новый элемент внутри элемента после определений строк и столбцов, а затем присвойте ему строковое значение Names :
определяет содержимое Names . Некоторым элементам управления известно, как управлять содержимым, а другим — нет. Содержимое элемента управления сопоставляется со свойством Content . При задании содержимого с помощью синтаксиса атрибутов XAML можно использовать следующий формат:
. Оба способа служат для выполнения одного и того же действия — отображение текста Names в качестве содержимого метки.
У нас есть проблема, поскольку метка занимает половину окна, так как она была автоматически назначена первой строке и столбцу сетки. Для первой строки нам не нужно много пространства, поскольку мы будем использовать эту строку только для метки. Измените атрибут Height первого параметра с * на Auto . Значение Auto автоматически изменяет размер строки сетки под размер ее содержимого (в данном случае это элемент управления Label).
Обратите внимание, что теперь в конструкторе отображается метка, занимающая небольшую часть доступной высоты. Теперь имеется больше места для следующей строки. Большинство элементов управления определяют значения высоты и ширины, которые они должны занимать. Например, элемент управления "метка" имеет значение высоты, которое гарантирует, что его можно прочитать.
Размещение элементов управления
Давайте поговорим о размещении элементов управления. Метка, созданная в разделе выше, автоматически помещается в строку 0 и столбец 0 сетки. Нумерация строк и столбцов начинается с 0 и увеличивается на 1 для каждой новой строки или столбца. Элементу управления ничего не известно о сетке, и элемент управления не определяет свойства для управления своим размещением в сетке. Элемент управления может быть даже помещен в другой элемент управления макета, имеющий собственный набор правил, определяющих способ размещения элементов управления.
Как указать элементу управления, что ему следует использовать другую строку или столбец, если элемент управления не имеет сведений о сетке? В этом случае на помощь придут вложенные свойства! Сетка использует эффективную систему свойств, предоставляемую WPF. Сетка определяет новые свойства, которые дочерние элементы управления могут объявлять и использовать. Свойства фактически не существуют в самом элементе управления, они вкладываются сеткой при добавлении элемента управления в сетку.
Сетка определяет два свойства для определения размещения строк и столбцов дочернего элемента управления: Grid.Row и Grid.Column . Если эти свойства опущены в элементе управления, предполагается, что они имеют значения по умолчанию 0, поэтому элемент управления помещается в строку 0 и столбец 0 сетки. Попробуйте изменить расположение элемента управления , присвоив атрибуту Grid.Column значение 1 :
Обратите внимание, что метка теперь переместилась во второй столбец. Вложенные свойства Grid.Row и Grid.Column можно использовать для размещения последующих элементов управления, которые мы создадим. Но на этом этапе следует вернуть метку в строку 0.
Создание поля со списком имен
Теперь, когда сетка имеет правильный размер и создана метка, добавьте элемент управления "Список" в строку под меткой. Список будет находиться в строке 1 и столбце 0 . Присвоим этому элементу управления имя lstNames . После именования элемента управления на него можно ссылаться в коде программной части. Имя присваивается элементу управления с помощью атрибута x:Name .
Добавление оставшихся элементов управления
Последние два элемента управления, которые предстоит добавить, — это текстовое поле и кнопка, которые пользователь будет использовать для ввода имени, добавляемого в список. Однако вместо того, чтобы пытаться создать больше строк и столбцов для сетки, эти элементы управления будут размещены в элементе управления .
Панель стека отличается от сетки тем, как в ней размещаются элементы управления. В сетке для указания того, где должны располагаться элементы управления, вы используете свойства Grid.Row и Grid.Column , тогда как в панели стека это выполняется автоматически: сначала размещается первый элемент управления, затем после него следующий элемент управления, и так до тех пор, пока не будут размещены все элементы управления. Элементы управления размещаются в "стек" один под другим.
Создайте элемент управления после списка и вставьте его в строку 1 и столбец 1 сетки. Добавьте еще один атрибут с именем Margin и значением 5,0,0,0 :
Атрибут Margin ранее уже использовался в сетке, однако теперь мы поместим только одно значение, 10 . Мы использовали значение 5,0,0,0 в панели стека. Поле является типом Thickness и может интерпретировать оба значения. Толщина определяет пространство вокруг каждой стороны прямоугольника, слева, сверху, справа, снизу, соответственно. Если значение поля является одним значением, оно используется для всех четырех сторон.
Затем создайте и элемент управления в .
Макет окна готов. Однако в наше приложение следует добавить логику, чтобы оно работало. Далее необходимо подключить события элемента управления к коду, чтобы приложение выполняло действия.
Добавление кода для события Click
Созданная нами кнопка имеет событие Click , возникающее, когда пользователь нажимает кнопку. Можно подписаться на это событие и добавить код, который будет добавлять имя в список. Как и при задании свойства элемента управления путем добавления атрибута XAML, можно использовать атрибут XAML для подписки на событие. Задайте для атрибута Click значение ButtonAddName_Click .
Теперь необходимо создать код обработчика. Щелкните правой кнопкой мыши ButtonAddName_Click и выберите Перейдите к определению. Это действие создает метод в коде программной части, который соответствует введенному имени обработчика.
Затем добавьте следующий код для выполнения следующих трех шагов:
- Проверка того, что в текстовом поле содержится имя.
- Проверка того, что имя, указанное в текстовом поле, еще не добавлено.
- Добавление имени в список.
Запустите приложение
Теперь, когда у нас есть код события, можно запустить приложение, нажав клавишу F5 или выбрав пункт меню Отладка>Начать отладку. Отобразится окно, и вы можете ввести имя в текстовое поле, а затем добавить его, нажав кнопку.
In this short tutorial, you'll learn how to create a new Windows Presentation Foundation (WPF) app with Visual Studio. Once the initial app has been generated, you'll learn how to add controls and how to handle events. By the end of this tutorial, you'll have a simple app that adds names to a list box.
In this tutorial, you learn how to:
- Create a new WPF app
- Add controls to a form
- Handle control events to provide app functionality
- Run the app
Here's a preview of the app you'll build while following this tutorial:
Prerequisites
Create a WPF app
The first step to creating a new app is opening Visual Studio and generating the app from a template.
Open Visual Studio.
Select Create a new project.
In the Search for templates box, type wpf, and then press Enter .
In the templates list, select WPF Application and then select Next.
In the Configure your new project window, do the following:
- In the Project name box, enter Names.
- Select the Place solution and project in the same directory check box.
- Optionally, choose a different Location to save your code.
- Select the Next button.
Open Visual Studio.
Select Create a new project.
In the Search for templates box, type wpf, and then press Enter .
In the templates list, select WPF Application and then select Next.
In the Configure your new project window, do the following:
- In the Project name box, enter Names.
- Select the Place solution and project in the same directory check box.
- Optionally, choose a different Location to save your code.
- Select the Next button.
Once the app is generated, Visual Studio should open the XAML designer pane for the default window, MainWindow. If the designer isn't visible, double-click on the MainWindow.xaml file in the Solution Explorer pane to open the designer.
Important parts of Visual Studio
Support for WPF in Visual Studio has five important components that you'll interact with as you create an app:
All of your project files, code, windows, resources, will appear in this pane.
This pane shows property settings you can configure based on the item selected. For example, if you select an item from Solution Explorer, you'll see property settings related to the file. If you select an object in the Designer, you'll see settings for that item.
The toolbox contains all of the controls you can add to a form. To add a control to the current form, double-click a control or drag-and-drop the control.
This is the designer for a XAML document. It's interactive and you can drag-and-drop objects from the Toolbox. By selecting and moving items in the designer, you can visually compose the user interface (UI) for your app.
When both the designer and editor are visible, changes to one is reflected in the other. When you select items in the designer, the Properties pane displays the properties and attributes about that object.
XAML code editor
This is the XAML code editor for a XAML document. The XAML code editor is a way to craft your UI by hand without a designer. The designer may infer the values of properties on a control when the control is added in the designer. The XAML code editor gives you a lot more control.
When both the designer and editor are visible, changes to one is reflected in the other. As you navigate the text caret in the code editor, the Properties pane displays the properties and attributes about that object.
Examine the XAML
After your project is created, the XAML code editor is visible with a minimal amount of XAML code to display the window. If the editor isn't open, double-click the MainWindow.xaml item in the Solution Explorer. You should see XAML similar to the following example:
The document root represents the type of object being described by the XAML file. There are eight attributes declared, and they generally belong to three categories:
An XML namespace provides structure to the XML, determining what XML content can be declared in the file.
The main xmlns attribute imports the XML namespace for the entire file, and in this case, maps to the types declared by WPF. The other XML namespaces declare a prefix and import other types and objects for the XAML file. For example, the xmlns:local namespace declares the local prefix and maps to the objects declared by your project, the ones declared in the Names code namespace.
This attribute maps the to the type defined by your code: the MainWindow.xaml.cs or MainWindow.xaml.vb file, which is the Names.MainWindow class.
Any normal attribute declared on the XAML object sets a property of that object. In this case, the Title attribute sets the Window.Title property.
Change the window
First, run the project and see the default output. You'll see a window that pops up, without any controls, and a title of MainWindow:
For our example app, this window is too large, and the title bar isn't descriptive. Change the title and size of the window by changing the appropriate attributes in the XAML to the following values:
Prepare the layout
WPF provides a powerful layout system with many different layout controls. Layout controls help place and size child controls, and can even do so automatically. The default layout control provided to you in this XAML is the control.
The Grid control lets you define rows and columns, much like a table, and place controls within the bounds of a specific row and column combination. You can have any number of child controls or other layout controls added to the Grid . For example, you can place another Grid control in a specific row and column combination, and that new Grid can then define more rows and columns and have its own children.
The control defines rows and columns in which your controls will be. A grid always has a single row and column declared, meaning, the grid by default is a single cell. That doesn't really give you much flexibility in placing controls.
Before we add the new rows and columns, add a new attribute to the element: Margin="10" . This insets the grid from the window and makes it look a little nicer.
Next, define two rows and two columns, dividing the grid into four cells:
Select the grid in either the XAML code editor or XAML designer, you'll see that the XAML designer shows each row and column:
Add the first control
Now that the grid has been created, we can start adding controls to it. First, start with the label control. Create a new element inside the element, after the row and column definitions, and give it a string value of Names :
The defines the content Names . Some controls understand how to handle content, others don't. The content of a control maps to the Content property. Setting the content through XAML attribute syntax, you would use this format:
. Both ways accomplish the same thing, setting the content of the label to display the text Names .
We have a problem though, the label takes up half the window as it was automatically assigned to the first row and column of the grid. For our first row, we don't need that much space because we're only going to use that row for the label. Change the Height attribute of the first from * to Auto . The Auto value automatically sizes the grid row to the size of its contents, in this case, the label control.
Notice that the designer now shows the label occupying a small amount of the available height. There's now more room for the next row to occupy. Most controls define some sort of height and width value that they should occupy that looks best for them. For example, the label control has a height value that ensures that you can read it.
Control placement
Let's talk about control placement. The label created in the section above was automatically placed in row 0 and column 0 of the grid. The numbering for rows and columns starts at 0 and increments by 1 for each new row or column. The control doesn't know anything about the grid, and the control doesn't define any properties to control its placement within the grid. The control could have even been placed within some other layout control that has its own set of rules defining how to place controls.
How do you tell a control to use a different row or column when the control has no knowledge of the grid? Attached properties! The grid takes advantage of the powerful property system provided by WPF. The grid defines new properties that the child controls can declare and use. The properties don't actually exist on the control itself, they're attached by the grid when the control is added to the grid.
The grid defines two properties to determine the row and column placement of a child control: Grid.Row and Grid.Column . If these properties are omitted from the control, it's implied that they have the default values of 0, so, the control is placed in row 0 and column 0 of the grid. Try changing the placement of the control by setting the Grid.Column attribute to 1 :
Notice how your label now moved to the second column. You can use the Grid.Row and Grid.Column attached properties to place the next controls we'll create. For now though, restore the label to row 0.
Create the name list box
Now that the grid is correctly sized and the label created, add a list box control on the row below the label. The list box will be in row 1 and column 0 . We'll also give this control the name of lstNames . Once a control is named, it can be referenced in the code-behind. The name is assigned to the control with the x:Name attribute.
Add the remaining controls
The last two controls we'll add are a text box and a button, which the user will use to enter a name to add to the list box. However, instead of trying to create more rows and columns for the grid, we'll put these controls into the layout control.
The stack panel differs from the grid in how the controls are placed. While you tell the grid where you want the controls to be with the Grid.Row and Grid.Column attached properties, the stack panel works automatically by placing the first control, then placing the next control after it, continuing until all controls have been placed. It "stacks" each control below the other.
Create the control after the list box and put it in grid row 1 column 1 . Add another attribute named Margin with a value of 5,0,0,0 :
The Margin attribute was previously used on the grid, but we only put in a single value, 10 . Now we've used a value of 5,0,0,0 on the stack panel. The margin is a Thickness type and can interpret both values. A thickness defines the space around each side of a rectangular frame, left, top, right, bottom, respectively. If the value for the margin is a single value, it uses that value for all four sides.
Next, create a and control in the .
The layout for the window is complete. However, our app doesn't have any logic in it to actually be functional. Next, we need to hook up the control events to code and get the app to actually do something.
Add code for the Click event
The we created has a Click event that is raised when the user presses the button. You can subscribe to this event and add code to add a name to the list box. Just like you set a property on a control by adding a XAML attribute, you can use a XAML attribute to subscribe to an event. Set the Click attribute to ButtonAddName_Click
Now you need to generate the handler code. Right-click on ButtonAddName_Click and select Go To Definition. This action generates a method in the code-behind for you that matches the handler name you've entered.
Next, add the following code to do these three steps:
- Make sure that the text box contains a name.
- Validate that the name entered in the text box doesn't already exist.
- Add the name to the list box.
Run the app
Now that the event has been coded, you can run the app by pressing the F5 key or by selecting Debug > Start Debugging from the menu. The window is displayed and you can enter a name in the textbox and then add it by clicking the button.
После установки среды и всех ее компонентов, запустим Visual Studio и создадим проект графического приложения. На стартовом экране выберем Create a new project (Создать новый проект)
На следующем окне в качестве типа проекта выберем WPF Application :
Далее на следующем этапе нам будет предложено указать имя проекта и каталог, где будет располагаться проект.
В поле Project Name дадим проекту какое-либо название. В моем случае это HelloApp .
После этого Visual Studio откроет наш проект с созданными по умолчанию файлами:
Структура проекта
Справа находится окно Solution Explorer, в котором можно увидеть структуру нашего проекта. В данном случае у нас сгенерированная по умолчанию структура:
App.xaml задает ресурсы приложения и ряд конфигурационных настроек в виде кода XAML. В частности, в файле App.xaml задается файл окна программы, которое будет открываться при запуске приложения. Если вы откроете этот файл, то можете найти в нем строку StartupUri="MainWindow.xaml" - то есть в данном случае, когда мы запустим приложение, будет создаваться интерфейс из файла MainWindow.xaml .
AssemblyInfo.cs содержит информацию о создаваемой в процессе компиляции сборке
MainWindow.xaml представляет визуальный интерфейс окна приложения в виде кода XAML.
По умолчанию эти файлы открыти в текстовом редакторе Visual Studio. Причем файл MainWindow.xaml имеет два представления: визуальное - в режиме WYSIWIG отображает весь графический интерфейс данного окна приложения, и под ним декларативное объявление интерфейса в XAML. Если мы изменим декларативную разметку, например, определим там кнопку, то эти изменения отображаться в визуальном представлении. Таким образом, мы сможем сразу же получить представление об интерфейсе окна приложения.
Настройка компиляции проекта
В итоге нам откроектся файл с расширением csproj , который называется по имени проекта (например, HelloApp.csproj) со следующим содержимым:
Для компиляции приложения WPF указаны следующие настройки:
OutputType : определяет выходной тип проекта. Должен иметь значение WinExe - то есть выполняемое приложение с расширением exe под Windows
Nullable : подключает в проект функциональность ссылочных nullable-типов
UseWPF : указывает, будет ли проект использовать WPF. (при значении true проект использует WPF)
Запуск проекта
Чтобы запустить приложение в режиме отладки, нажмем на клавишу F5 или на зеленую стрелочку на панели Visual Studio. И после этого запустится пустое окно по умолчанию.
После запуска приложения студия компилирует его в файл с расширением exe. Найти данный файл можно, зайдя в папку проекта и далее в каталог \bin\Debug\net6.0-windows
Рассмотрев вкратце создание проекта графического приложения, мы можем перейти к обзору основных компонентов и начнем мы с форм.
Создание первого приложения
Однако приложение с пустым окном - не слишком показательный пример. Добавим в него чуть больше функционала. Для этого откроем файл логики кода окна приложения - MainWindow.xaml.cs . Сейчас он имеет следующий код:
Здесь определен класс MainWindow, который наследуется от класса Window и берет от него всю базовую функциональность окон. А в конструкторе этого класса вызывается метод InitializeComponent() , который позволяет применить интерфейс из файла MainWindow.xaml .
Теперь изменим файл MainWindow.xaml.cs следующим образом:
Теперь определим саму кнопку. Для этого перейдем к файлу MainWindow.xaml , который содержит разметку визуального интерфейса в виде кода XAML. По умолчанию он имее следующее содержимое:
XAML в целом напоминает язык разметки HTML: здесь у нас сначала определен элемент верхнего уровня Window - окно приложения, в нем определено элемент Grid - контейнер верхнего уровня, в который мы можем добавлять другие элементы. Каждый элемент может иметь определенные атрибуты. Более подробно с языком XAML и элементами мы познакомимся позднее, а пока изменим эту разметку на следующую:
Для определения кнопки внутри элемента Grid определен элемент Button . Для этого элемента с помощью атрибутов можно установать различные его характеристика. Так, в данном случае устанавливаются следующие атрибуты:
Content : содержимое кнопки
FontSize : высота шрифта
Width : ширина кнопки
Height : высота кнопки
По разным причинам большинство из нас использует десктопные приложения, как минимум, браузер :) А у некоторых из нас возникает необходимость в написании своих. В этой статье я хочу пробежаться по процессу разработки несложного десктопного приложения с использованием технологии Windows Presentation Foundation (WPF) и применением паттерна MVVM. Желающих продолжить чтение прошу под кат.
В чём особенность WPF?
Два основных отличия WPF от других средств построения десктопных приложений:
- Язык разметки XAML, предназначенный для разметки самого интерфейса окна.
- Рендеринг посредством DirectX, аппаратное ускорение графики.
Я не буду углубляться в подробности, т.к. это не совсем тема статьи. Если интересно, то гуглить XAML, WPF rendering, milcore.dll и DirectX :)
О чём эта статья?
Эта статья содержит пример приложения, построенного на технологии WPF:
Я постараюсь ориентировать материал статьи в практическую сторону в стиле "повторяй за мной" с пояснениями.
Что нам понадобится для повторения статьи?
Так же в этом разделе я опишу создание проекта.
После создания нового проекта откроется окно редактора интерфейса, у меня оно выглядит так
Внизу находится редактор разметки, вверху — предпросмотр интерфейса окна, но можно поменять относительное расположение редактора кода и предпросмотра интерфейса так, что они будут располагаться в горизонтальном порядке, с помощью вот этих кнопок (справа на границе двух областей):
Перед тем, как начать
Элементы окна (их ещё называют контрОлами от слова Control) должны размещаться внутри контейнера или внутри другого элемента типа ContentControl. Контейнер — это специальный контрол, позволяющий разместить внутри себя несколько дочерних контролов и организовать их взаимное расположение. Примеры контейнеров:
- Grid — позволяет организовать элементы по столбцам и строкам, ширина каждого столбца или строки настраивается индивидуально.
- StackPanel — позволяет расположить дочерние элементы в одну строку или столбец.
Есть и другие контейнеры. Поскольку контейнер тоже является контролом, то внутри контейнера могут быть вложенные контейнеры, содержащие вложенные контейнеры и так далее. Это позволяет гибко располагать контролы относительно друг друга. Так же с помощью контейнеров мы можем не менее гибко управлять поведением вложенных контролов при изменении размеров окна.
MVVM и интерфейс INotifyPropertyChanged. Копия текста.
Итогом этого примера станет приложение с двумя контролами, в одном из которых можно редактировать текст, а в другом только просматривать. Изменения из одного в другой будут переходить синхронно без явного копирования текста с помощью привязки (binding).
Итак, у нас есть свежесозданный проект (я назвал его Ex1), перейдём в редактор разметки и первым делом заменим контейнер, указанный по умолчанию ( ) на . Этого контейнера будет достаточно, т.к. нам понадобится расположить всего лишь два контрола один над другим. Укажем явно, каким образом будут располагаться компоненты, добавив свойство Orientation="Vertical". Добавим внутрь стек панели парочку элементов: поле для ввода текста и поле для отображения текста. Поскольку эти контролы не будут содержать вложенного кода, можно описать их самозакрывающимся тегом (см. код ниже). После всех вышеописанных процедур код описания контейнера и вложенных контролов должен принять такой вид:
Мы сделали привязку, но пока непонятно к чему :) Нам нужен объект какого-то класса и какое-то свойство в этом объекте, к которому будет выполнена привязка (как ещё говорят, на которое нужно забиндиться).
Так что это за класс? Этот класс называется вьюмоделью (view model) и служит как раз связующим звеном между view (интерфейсом или его частями) и model (моделью, т.е. теми частями кода, которые отвечают за логику приложения. Это позволяет отделить (в какой-то степени) логику приложения от интерфейса (представления, view) и называется паттерном Model-View-ViewModel (MVVM). В рамках WPF этот класс также называется DataContext.
Однако, просто написать класс вьюмодели недостаточно. Нужно ещё как-то оповещать механизм привязки о том, что свойство вьюмодели или свойство вью изменилось. Для этого существует специальный интерфейс INotifyPropertyChanged, который содержит событие PropertyChanged. Реализуем этот интерфейс в рамках базового класса BaseViewModel. В дальнейшем все наши вьюмодели мы будем наследовать от этого базового класса, чтобы не дублировать реализацию интерфейса. Итак, добавим в проект каталог ViewModels, а в этот каталог добавим файл BaseViewModel.cs. Получим такую структуру проекта:
Код реализации базовой вьюмодели:
Создадим для нашего класса MainWindow свою вьюмодель, унаследовавшись от базовой. Для этого в том же каталоге ViewModels создадим файл MainWindowViewModel.cs, внутри которого будет такой код:
Шикарно! Теперь нужно добавить в эту вьюмодель свойство, на которое будем биндить текст наших контролов. Поскольку это текст, тип этого свойства должен быть string:
В итоге получим такой код
Так, кажется, справились. Осталось забиндиться на это свойство из вьюхи и готово. Давайте сделаем это прямо сейчас:
Ништяк, запускаем проект, набираем текст в текстбокс иииии… ничего не происходит))) Ну, ничего страшного, на самом деле мы идём правильной дорогой, просто пока ещё не дошли до нужной точки.
Предлагаю на минутку остановиться и подумать, чего же нам не хватает. Вьюха у нас есть. Вьюмодель тоже. Свойства вроде забиндили. Нужный интерфейс реализовали. Проделали кучу работы ради копирования жалкой строчки текста, за что нам это. 111
Ладно, шутки в сторону. Мы забыли создать объект вьюмодели и кое-что ещё (об этом позже). Сам класс мы описали, но это ничего не значит, ведь у нас нет объектов этого класса. Ок, где нужно хранить ссылку на этот объект? Ближе к началу примера я упомянул некий DataContext, используемый в WPF. Так вот, у любой вью есть свойство DataContext, которому мы можем присвоить ссылку на нашу вьюмодель. Сделаем это. Для этого откроем файл MainWindow.xaml и нажмём F7, чтобы открыть код этой вьюхи. Он практически пустой, в нём есть только конструктор класса окна. Добавим в него создание нашей вьюмодели и поместим её в DataContext окна (не забываем добавить using с нужным неймспейсом):
Это было просто, но этого всё равно не хватает. По-прежнему при запуске приложения никакой синхронизации текста не происходит. Что ещё нужно сделать?
Нужно вызвать событие PropertyChanged при изменении свойства SynchronizedText и сообщить вьюхе о том, что она должна следить за этим событием. Итак, чтобы вызвать событие, модифицируем код вьюмодели:
Что мы тут сделали? Добавили скрытое поле для хранения текста, обернули его в уже существующее свойство, а при изменении этого свойства не только меняем скрытое поле, но и вызываем метод OnPropertyChanged, определённый в базовой вьюмодели и вызывающий событие PropertyChanged, объявленное в интерфейсе INotifyPropertyChanged, так же реализованное в базовой вьюмодели. Получается, что при каждом изменении текста возникает событие PropertyChanged, которому передаётся имя свойства вьюмодели, которое было изменено.
Ну, почти всё, финишная прямая! Осталось указать вьюхе, что оно должно слушать событие PropertyChanged:
Помимо того, что мы указали, по какому триггеру должно происходить обновление, мы так же указали, в какую сторону это обновление отслеживается: от вью к вьюмодели или наоборот. Поскольку в текстбоксе мы вводим текст, то нам интересны изменения только во вью, поэтому выбираем режим OneWayToSource. В случае с текстблоком всё ровно наоборот: нам интересны изменения во вьюмодели, чтобы отобразить их во вью, поэтому выбираем режим OneWay. Если бы нам нужно было, чтобы изменения отслеживались в обе стороны, можно было не указывать Mode вообще, либо указать TwoWay явно.
Итак, запускаем программу, набираем текст и voi-la! Текст синхронно меняется, и мы нигде ничего не копировали!
Спасибо за внимание, продолжение следует. Будем разбираться с DataTemplate и паттерном Command.
Читайте также: