WPF — Обзор
WPF расшифровывается как Windows Presentation Foundation. Это мощная платформа для создания приложений Windows. В этом руководстве объясняются функции, которые вам необходимо понять для создания приложений WPF, и как он вносит фундаментальные изменения в приложения Windows.
WPF был впервые представлен в .NET Framework 3.0 версии, а затем в последующих версиях .NET Framework было добавлено много других функций.
WPF Архитектура
До WPF другие платформы пользовательского интерфейса, предлагаемые Microsoft, такие как формы MFC и Windows, были просто оболочками вокруг DLL-файлов User32 и GDI32, но WPF использует User32 лишь минимально. Так,
- WPF — это больше, чем просто обертка.
- Это часть .NET Framework.
- Он содержит смесь управляемого и неуправляемого кода.
Основные компоненты архитектуры WPF показаны на рисунке ниже. Наиболее важная часть кода WPF —
- Структура представления
- Ядро презентации
- Milcore
Структура представления и ядро представления были написаны в управляемом коде. Milcore является частью неуправляемого кода, который обеспечивает тесную интеграцию с DirectX (отвечает за отображение и рендеринг). CLR делает процесс разработки более продуктивным, предлагая множество функций, таких как управление памятью, обработка ошибок и т. Д.
WPF — Преимущества
В более ранних платформах GUI не было никакого реального разделения между тем, как приложение выглядит и как оно себя ведет. И GUI, и поведение были созданы на одном языке, например, C # или VB.Net, что потребует от разработчика больших усилий для реализации как пользовательского интерфейса, так и поведения, связанного с ним.
В WPF элементы пользовательского интерфейса разработаны в XAML, а поведение может быть реализовано на процедурных языках, таких как C # и VB.Net. Так что очень легко отделить поведение от кода дизайнера.
С XAML программисты могут работать параллельно с дизайнерами. Разделение между GUI и его поведением может позволить нам легко изменить внешний вид элемента управления с помощью стилей и шаблонов.
WPF — Особенности
WPF — это мощная среда для создания приложений Windows. Он поддерживает много замечательных функций, некоторые из которых были перечислены ниже —
Особенность | Описание |
---|---|
Контроль внутри элемента управления | Позволяет определить элемент управления внутри другого элемента управления как контент. |
Привязка данных | Механизм отображения и взаимодействия с данными между элементами пользовательского интерфейса и объектом данных в пользовательском интерфейсе. |
Медиа услуги | Предоставляет интегрированную систему для создания пользовательских интерфейсов с общими элементами мультимедиа, такими как изображения, аудио и видео. |
Шаблоны | В WPF вы можете определить внешний вид элемента непосредственно с помощью шаблона |
Анимации | Построение интерактивности и движения на пользовательском интерфейсе |
Альтернативный ввод | Поддерживает мультитач-ввод в Windows 7 и выше. |
Direct3D | Позволяет отображать более сложную графику и пользовательские темы |
WPF — Настройка среды
Microsoft предоставляет два важных инструмента для разработки приложений WPF.
- Visual Studio
- Выражение смесь
Оба инструмента могут создавать проекты WPF, но факт заключается в том, что Visual Studio больше используется разработчиками, а Blend чаще используется дизайнерами. Для этого урока мы в основном будем использовать Visual Studio.
Монтаж
Microsoft предоставляет бесплатную версию Visual Studio, которую можно загрузить с VisualStudio .
Загрузите файлы и следуйте приведенным ниже инструкциям, чтобы настроить среду разработки приложений WPF в своей системе.
-
После завершения загрузки запустите установщик . Следующий диалог будет отображен.
После завершения загрузки запустите установщик . Следующий диалог будет отображен.
-
Нажмите кнопку Установить , и он начнет процесс установки.
Нажмите кнопку Установить , и он начнет процесс установки.
-
Как только процесс установки завершится успешно, вы увидите следующее диалоговое окно.
Как только процесс установки завершится успешно, вы увидите следующее диалоговое окно.
-
Закройте это диалоговое окно и перезагрузите компьютер, если это необходимо.
-
Теперь откройте Visual Studio из меню «Пуск», которое откроет следующее диалоговое окно.
Закройте это диалоговое окно и перезагрузите компьютер, если это необходимо.
Теперь откройте Visual Studio из меню «Пуск», которое откроет следующее диалоговое окно.
- Как только все будет сделано, вы увидите главное окно Visual Studio.
Теперь вы готовы создать свое первое приложение WPF.
WPF — Hello World
В этой главе мы разработаем простое WPF-приложение Hello World. Итак, давайте начнем простую реализацию, следуя шагам, приведенным ниже.
- Нажмите Файл> Создать> Пункт меню Проект.
- Появится следующее диалоговое окно.
-
В разделе «Шаблоны» выберите Visual C # и на средней панели выберите «Приложение WPF».
-
Дайте проекту имя. Введите HelloWorld в поле имени и нажмите кнопку ОК.
-
По умолчанию создаются два файла, один из которых является файлом XAML (mainwindow.xaml), а другой — файлом CS (mainwindow.cs).
-
В mainwindow.xaml вы увидите два подокна, одно — окно дизайна, а другое — окно исходного кода (XAML).
-
В приложении WPF существует два способа создания пользовательского интерфейса для вашего приложения. Одним из них является просто перетаскивание элементов пользовательского интерфейса из панели инструментов в окно дизайна. Второй способ — создать свой пользовательский интерфейс, написав теги XAML для элементов пользовательского интерфейса. Visual Studio обрабатывает теги XAML, когда для проектирования пользовательского интерфейса используется функция перетаскивания.
-
В файле mainwindow.xaml следующие теги XAML записываются по умолчанию.
В разделе «Шаблоны» выберите Visual C # и на средней панели выберите «Приложение WPF».
Дайте проекту имя. Введите HelloWorld в поле имени и нажмите кнопку ОК.
По умолчанию создаются два файла, один из которых является файлом XAML (mainwindow.xaml), а другой — файлом CS (mainwindow.cs).
В mainwindow.xaml вы увидите два подокна, одно — окно дизайна, а другое — окно исходного кода (XAML).
В приложении WPF существует два способа создания пользовательского интерфейса для вашего приложения. Одним из них является просто перетаскивание элементов пользовательского интерфейса из панели инструментов в окно дизайна. Второй способ — создать свой пользовательский интерфейс, написав теги XAML для элементов пользовательского интерфейса. Visual Studio обрабатывает теги XAML, когда для проектирования пользовательского интерфейса используется функция перетаскивания.
В файле mainwindow.xaml следующие теги XAML записываются по умолчанию.
<Window x:Class = "HelloWorld.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> <Grid> </Grid> </Window>
- По умолчанию сетка устанавливается в качестве первого элемента после страницы.
- Давайте перейдем к панели инструментов и перетащим TextBlock в окно дизайна.
- Вы увидите TextBlock в окне дизайна.
-
Когда вы посмотрите на исходное окно, вы увидите, что Visual Studio сгенерировал XAML-код TextBlock для вас.
-
Давайте изменим свойство Text TextBlock в коде XAML с TextBlock на Hello World.
Когда вы посмотрите на исходное окно, вы увидите, что Visual Studio сгенерировал XAML-код TextBlock для вас.
Давайте изменим свойство Text TextBlock в коде XAML с TextBlock на Hello World.
<Window x:Class = "HelloWorld.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <TextBlock x:Name = "textBlock" HorizontalAlignment = "Left" Margin = "235,143,0,0" TextWrapping = "Wrap" Text = "Hello World!" VerticalAlignment = "Top" Height = "44" Width = "102" /> </Grid> </Window>
- Теперь вы также увидите изменения в окне дизайна.
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно.
Поздравляем! Вы разработали и создали свое первое приложение WPF.
WPF — XAML Обзор
Одна из первых вещей, с которой вы столкнетесь при работе с WPF, — это XAML. XAML расшифровывается как расширяемый язык разметки приложений. Это простой и декларативный язык, основанный на XML.
-
В XAML очень легко создавать, инициализировать и устанавливать свойства объектов с иерархическими отношениями.
-
Он в основном используется для разработки графических интерфейсов, однако может использоваться и для других целей, например, для объявления рабочего процесса в Workflow Foundation.
В XAML очень легко создавать, инициализировать и устанавливать свойства объектов с иерархическими отношениями.
Он в основном используется для разработки графических интерфейсов, однако может использоваться и для других целей, например, для объявления рабочего процесса в Workflow Foundation.
Основной синтаксис
Когда вы создаете новый проект WPF, вы встретите код XAML по умолчанию в MainWindow.xaml, как показано ниже.
<Window x:Class = "Resources.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "525"> <Grid> </Grid> </Window>
Приведенный выше файл XAML содержит различные виды информации. Следующая таблица кратко объясняет роль каждой информации.
Информация | Описание |
---|---|
<Window | Это открываемый элемент объекта или контейнер корня. |
x: Class = «Resources.MainWindow» | Это частичное объявление класса, которое связывает разметку с частичным кодом класса, определенным позади. |
xmlns = «http://schemas.microsoft.com/win fx / 2006 / xaml / presentation» | Сопоставляет пространство имен XAML по умолчанию для клиента / инфраструктуры WPF |
xmlns: x = «http://schemas.microsoft.com/w infx / 2006 / xaml» | Пространство имен XAML для языка XAML, которое сопоставляет его с префиксом x: |
> | Конец объекта элемента корня |
<Grid> </ Grid> |
Это запуск и закрытие тегов пустого объекта сетки. |
</ Window> | Закрытие элемента объекта |
<Grid>
</ Grid>
Правила синтаксиса для XAML почти аналогичны XML. Если вы посмотрите на документ XAML, то заметите, что это действительно допустимый XML-файл, но XML-файл не обязательно является XAML-файлом. Это связано с тем, что в XML значение атрибутов должно быть строкой, а в XAML это может быть другой объект, известный как синтаксис элемента Property.
-
Синтаксис элемента Object начинается с левой угловой скобки (<), за которой следует имя объекта, например, Button.
-
Определите некоторые свойства и атрибуты этого элемента объекта.
-
Элемент Object должен быть закрыт косой чертой (/), за которой сразу следует правая угловая скобка (>).
Синтаксис элемента Object начинается с левой угловой скобки (<), за которой следует имя объекта, например, Button.
Определите некоторые свойства и атрибуты этого элемента объекта.
Элемент Object должен быть закрыт косой чертой (/), за которой сразу следует правая угловая скобка (>).
Пример простого объекта без дочернего элемента
<Button/>
Пример элемента объекта с некоторыми атрибутами
<Button Content = "Click Me" Height = "30" Width = "60" />
Пример альтернативного синтаксиса определяет свойства (синтаксис элемента свойства)
<Button> <Button.Content>Click Me</Button.Content> <Button.Height>30</Button.Height> <Button.Width>60</Button.Width> </Button>
Пример объекта с дочерним элементом: StackPanel содержит Textblock в качестве дочернего элемента
<StackPanel Orientation = "Horizontal"> <TextBlock Text = "Hello"/> </StackPanel>
Почему XAML в WPF
XAML — это не только самая широко известная функция WPF, но и одна из самых неправильно понятых. Если вы знакомы с WPF, значит, вы слышали о XAML; но обратите внимание на следующие два менее известных факта о XAML —
- WPF не нужен XAML
- XAML не нуждается в WPF
Они на самом деле отдельные технологии. Чтобы понять, как это может быть, давайте рассмотрим простой пример, в котором кнопка создается с некоторыми свойствами в XAML.
<Window x:Class = "WPFXAMLOverview.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> <StackPanel> <Button x:Name = "button" Content = "Click Me" HorizontalAlignment = "Left" Margin = "150" VerticalAlignment = "Top" Width = "75" /> </StackPanel> </Window>
Если вы решите не использовать XAML в WPF, то вы можете добиться того же результата с графическим интерфейсом, а также с процедурным языком. Давайте посмотрим на тот же пример, но на этот раз мы создадим кнопку в C #.
using System.Windows; using System.Windows.Controls; namespace WPFXAMLOverview { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // Create the StackPanel StackPanel stackPanel = new StackPanel(); this.Content = stackPanel; // Create the Button Button button = new Button(); button.Content = "Click Me"; button.HorizontalAlignment = HorizontalAlignment.Left; button.Margin = new Thickness(150); button.VerticalAlignment = VerticalAlignment.Top; button.Width = 75; stackPanel.Children.Add(button); } } }
Когда вы скомпилируете и выполните код XAML или код C #, вы увидите тот же вывод, как показано ниже.
Из приведенного выше примера ясно, что то, что вы можете сделать в XAML для создания, инициализации и установки свойств объектов, те же задачи могут быть выполнены с помощью кода.
-
XAML — это еще один простой и легкий способ разработки элементов пользовательского интерфейса.
-
С XAML это не означает, что то, что вы можете сделать для разработки элементов пользовательского интерфейса, является единственным способом. Вы можете объявить объекты в XAML или определить их с помощью кода.
-
XAML не обязателен, но, несмотря на это, он лежит в основе дизайна WPF.
-
Цель XAML — дать возможность визуальным дизайнерам создавать элементы пользовательского интерфейса напрямую.
-
WPF стремится сделать возможным управление всеми визуальными аспектами пользовательского интерфейса из разметки.
XAML — это еще один простой и легкий способ разработки элементов пользовательского интерфейса.
С XAML это не означает, что то, что вы можете сделать для разработки элементов пользовательского интерфейса, является единственным способом. Вы можете объявить объекты в XAML или определить их с помощью кода.
XAML не обязателен, но, несмотря на это, он лежит в основе дизайна WPF.
Цель XAML — дать возможность визуальным дизайнерам создавать элементы пользовательского интерфейса напрямую.
WPF стремится сделать возможным управление всеми визуальными аспектами пользовательского интерфейса из разметки.
WPF — Дерево элементов
Существует много технологий, в которых элементы и компоненты упорядочены в древовидной структуре, чтобы программисты могли легко обрабатывать объект и изменять поведение приложения. Windows Presentation Foundation (WPF) имеет комплексную древовидную структуру в виде объектов. В WPF существует два способа концептуализации целого дерева объектов:
- Логическая древовидная структура
- Визуальная древовидная структура
С помощью этих древовидных структур вы можете легко создавать и идентифицировать отношения между элементами пользовательского интерфейса. В основном, разработчики и дизайнеры WPF либо используют процедурный язык для создания приложения, либо проектируют часть пользовательского интерфейса приложения в XAML с учетом структуры дерева объектов.
Логическая древовидная структура
В приложениях WPF структура элементов пользовательского интерфейса в XAML представляет собой структуру логического дерева. В XAML основные элементы пользовательского интерфейса объявляются разработчиком. Логическое дерево в WPF определяет следующее:
- Свойства зависимости
- Статические и динамические ресурсы
- Привязка элементов к его названию и т. Д.
Давайте посмотрим на следующий пример, в котором создаются кнопка и поле со списком.
<Window x:Class = "WPFElementsTree.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> <StackPanel> <Button x:Name = "button" Height = "30" Width = "70" Content = "OK" Margin = "20" /> <ListBox x:Name = "listBox" Height = "100" Width = "100" Margin = "20"> <ListBoxItem Content = "Item 1" /> <ListBoxItem Content = "Item 2" /> <ListBoxItem Content = "Item 3" /> </ListBox> </StackPanel> </Window>
Если вы посмотрите на код XAML, вы увидите древовидную структуру, то есть корневым узлом является окно, а внутри корневого узла есть только один дочерний элемент, то есть StackPanel. Но StackPanel содержит два дочерних элемента, кнопку и список. У списка есть еще три дочерних элемента списка.
Визуальная древовидная структура
В WPF концепция визуального дерева описывает структуру визуальных объектов, представленных Visual Base Class. Он обозначает все элементы пользовательского интерфейса, которые отображаются на экране вывода.
Когда программист хочет создать шаблон для определенного элемента управления, он фактически отображает визуальное дерево этого элемента управления. Визуальное дерево также очень полезно для тех, кто хочет нарисовать элементы управления более низкого уровня по причинам производительности и оптимизации.
В приложениях WPF визуальное дерево используется для:
- Визуализация визуальных объектов.
- Рендеринг макетов.
- Маршрутизируемые события в основном движутся вдоль визуального дерева, а не логического дерева.
Чтобы увидеть визуальное дерево вышеупомянутого простого приложения, которое содержит кнопку и список, давайте скомпилируем и выполним код XAML, и вы увидите следующее окно.
Когда приложение запущено, вы можете увидеть визуальное дерево запущенного приложения в окне Live Visual Tree, которое показывает полную иерархию этого приложения, как показано ниже.
Визуальное дерево обычно является надмножеством логического дерева. Здесь вы можете видеть, что все логические элементы также присутствуют в визуальном дереве. Таким образом, эти два дерева на самом деле представляют собой просто два разных представления одного и того же набора объектов, составляющих пользовательский интерфейс.
-
Логическое дерево оставляет много деталей, позволяя вам сосредоточиться на основной структуре пользовательского интерфейса и игнорировать детали того, как именно он был представлен.
-
Логическое дерево — это то, что вы используете для создания базовой структуры пользовательского интерфейса.
-
Визуальное дерево будет интересно, если вы сосредоточитесь на презентации. Например, если вы хотите настроить внешний вид любого элемента пользовательского интерфейса, вам нужно будет использовать визуальное дерево.
Логическое дерево оставляет много деталей, позволяя вам сосредоточиться на основной структуре пользовательского интерфейса и игнорировать детали того, как именно он был представлен.
Логическое дерево — это то, что вы используете для создания базовой структуры пользовательского интерфейса.
Визуальное дерево будет интересно, если вы сосредоточитесь на презентации. Например, если вы хотите настроить внешний вид любого элемента пользовательского интерфейса, вам нужно будет использовать визуальное дерево.
WPF — Свойства зависимостей
В приложениях WPF свойство зависимости — это особый тип свойства, который расширяет свойство CLR. Он использует преимущества определенных функций, доступных в системе свойств WPF.
Класс, который определяет свойство зависимости, должен быть унаследован от класса DependencyObject . Многие из классов элементов управления пользовательского интерфейса, которые используются в XAML, являются производными от класса DependencyObject и поддерживают свойства зависимостей, например, класс Button поддерживает свойство зависимостей IsMouseOver .
Следующий код XAML создает кнопку с некоторыми свойствами.
<Window x:Class = "WPFDependencyProperty.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "clr-namespace:WPFDependencyProperty" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <Button Height = "40" Width = "175" Margin = "10" Content = "Dependency Property"> <Button.Style> <Style TargetType = "{x:Type Button}"> <Style.Triggers> <Trigger Property = "IsMouseOver" Value = "True"> <Setter Property = "Foreground" Value = "Red" /> </Trigger> </Style.Triggers> </Style> </Button.Style> </Button> </Grid> </Window>
Расширение разметки x: Type в XAML имеет аналогичную функциональность, как typeof () в C #. Он используется, когда указываются атрибуты, которые принимают тип объекта, например <Style TargetType = «{x: Type Button}»>>
Когда приведенный выше код скомпилирован и выполнен, вы получите следующее MainWindow . Когда мышь находится над кнопкой, она изменит цвет переднего плана кнопки. Когда мышь покидает кнопку, она меняет свой первоначальный цвет.
Почему нам нужны свойства зависимостей
Свойство Dependency дает вам все преимущества, когда вы используете его в своем приложении. Свойство зависимости можно использовать над свойством CLR в следующих сценариях:
- Если вы хотите установить стиль
- Если вы хотите привязку данных
- Если вы хотите установить с ресурсом (статический или динамический ресурс)
- Если вы хотите поддержать анимацию
По сути, свойства зависимости предлагают множество функций, которые вы не получите, используя свойство CLR.
Основное различие между свойствами зависимости и другими свойствами CLR перечислено ниже —
-
Свойства CLR могут напрямую читать / писать из закрытого члена класса, используя getter и setter . В отличие от свойств зависимости не хранятся в локальном объекте.
-
Свойства зависимостей хранятся в словаре пар ключ / значение, который предоставляется классом DependencyObject. Это также экономит много памяти, поскольку сохраняет свойства при изменении. Это также может быть связано в XAML.
Свойства CLR могут напрямую читать / писать из закрытого члена класса, используя getter и setter . В отличие от свойств зависимости не хранятся в локальном объекте.
Свойства зависимостей хранятся в словаре пар ключ / значение, который предоставляется классом DependencyObject. Это также экономит много памяти, поскольку сохраняет свойства при изменении. Это также может быть связано в XAML.
Пользовательские свойства зависимостей
В .NET Framework также могут быть определены пользовательские свойства зависимостей. Выполните шаги, указанные ниже, чтобы определить пользовательское свойство зависимости в C #.
-
Объявите и зарегистрируйте свойство зависимости с помощью регистра системных вызовов.
-
Предоставить установщик и получатель для свойства.
-
Определите статический обработчик, который будет обрабатывать любые изменения, которые происходят глобально
-
Определите обработчик экземпляра, который будет обрабатывать любые изменения, которые происходят с этим конкретным экземпляром.
Объявите и зарегистрируйте свойство зависимости с помощью регистра системных вызовов.
Предоставить установщик и получатель для свойства.
Определите статический обработчик, который будет обрабатывать любые изменения, которые происходят глобально
Определите обработчик экземпляра, который будет обрабатывать любые изменения, которые происходят с этим конкретным экземпляром.
Следующий код C # определяет свойство зависимостей для установки свойства SetText пользовательского элемента управления.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApplication3 { /// <summary> /// Interaction logic for UserControl1.xaml /// </summary> public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); } public static readonly DependencyProperty SetTextProperty = DependencyProperty.Register("SetText", typeof(string), typeof(UserControl1), new PropertyMetadata("", new PropertyChangedCallback(OnSetTextChanged))); public string SetText { get { return (string)GetValue(SetTextProperty); } set { SetValue(SetTextProperty, value); } } private static void OnSetTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { UserControl1 UserControl1Control = d as UserControl1; UserControl1Control.OnSetTextChanged(e); } private void OnSetTextChanged(DependencyPropertyChangedEventArgs e) { tbTest.Text = e.NewValue.ToString(); } } }
Вот файл XAML, в котором TextBlock определен как пользовательский элемент управления, и свойство Text будет назначено ему свойством зависимости SetText.
Следующий код XAML создает пользовательский элемент управления и инициализирует его свойство зависимостей SetText .
<Window x:Class = "WpfApplication3.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:views = "clr-namespace:WpfApplication3" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <views:UserControl1 SetText = "Hellow World"/> </Grid> </Window>
Давайте запустим это приложение. Вы можете сразу заметить, что в нашем MainWindow свойство зависимостей для пользовательского элемента управления было успешно использовано в качестве текста.
WPF — маршрутизируемые события
Маршрутизируемое событие — это тип события, которое может вызывать обработчики для нескольких слушателей в дереве элементов, а не только для объекта, вызвавшего событие. Это в основном событие CLR, которое поддерживается экземпляром класса Routed Event. Он зарегистрирован в системе событий WPF. RoutedEvents имеют три основные стратегии маршрутизации, которые заключаются в следующем —
- Прямое событие
- Бублинг событие
- Туннельное Событие
Прямое событие
Прямое событие аналогично событиям в формах Windows, которые создаются элементом, в котором происходит событие.
В отличие от стандартного события CLR, события с прямой маршрутизацией поддерживают обработку классов, и их можно использовать в установщиках событий и триггерах событий в вашем стиле пользовательского элемента управления.
Хорошим примером прямого события будет событие MouseEnter.
Бублинг событие
Событие барботирования начинается с элемента, из которого происходит событие. Затем он перемещается вверх по визуальному дереву к верхнему элементу визуального дерева. Итак, в WPF самый верхний элемент — это, скорее всего, окно.
Туннельное Событие
Вызываются обработчики событий в корне дерева элементов, и затем событие перемещается по визуальному дереву ко всем дочерним узлам, пока не достигнет элемента, в котором возникло событие.
Разница между пузырьковым и туннельным событиями заключается в том, что туннельное событие всегда начинается с предварительного просмотра.
В приложении WPF события часто реализуются в виде пары туннелирование / пузыри. Итак, у вас будет предварительный просмотр MouseDown, а затем событие MouseDown.
Ниже приведен простой пример маршрутизируемого события, в котором кнопка и три текстовых блока создаются с некоторыми свойствами и событиями.
<Window x:Class = "WPFRoutedEvents.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "450" Width = "604" ButtonBase.Click = "Window_Click" > <Grid> <StackPanel Margin = "20" ButtonBase.Click = "StackPanel_Click"> <StackPanel Margin = "10"> <TextBlock Name = "txt1" FontSize = "18" Margin = "5" Text = "This is a TextBlock 1" /> <TextBlock Name = "txt2" FontSize = "18" Margin = "5" Text = "This is a TextBlock 2" /> <TextBlock Name = "txt3" FontSize = "18" Margin = "5" Text = "This is a TextBlock 3" /> </StackPanel> <Button Margin = "10" Content = "Click me" Click = "Button_Click" Width = "80"/> </StackPanel> </Grid> </Window>
Вот код C # для реализации событий Click для Button, StackPanel и Window.
using System.Windows; namespace WPFRoutedEvents { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { txt1.Text = "Button is Clicked"; } private void StackPanel_Click(object sender, RoutedEventArgs e) { txt2.Text = "Click event is bubbled to Stack Panel"; } private void Window_Click(object sender, RoutedEventArgs e) { txt3.Text = "Click event is bubbled to Window"; } } }
Когда вы скомпилируете и выполните приведенный выше код, он выдаст следующее окно —
Когда вы нажимаете на кнопку, текстовые блоки обновляются, как показано ниже.
Если вы хотите остановить перенаправленное событие на каком-либо конкретном уровне, вам необходимо установить e.Handled = true;
Давайте изменим событие StackPanel_Click, как показано ниже —
private void StackPanel_Click(object sender, RoutedEventArgs e) { txt2.Text = "Click event is bubbled to Stack Panel"; e.Handled = true; }
При нажатии на кнопку вы увидите, что событие щелчка не будет направлено в окно и остановится на панели стека, а 3- й текстовый блок не будет обновлен.
Пользовательские маршрутизируемые события
В .NET Framework также можно определить настраиваемое перенаправленное событие. Чтобы определить настраиваемое перенаправленное событие в C #, необходимо выполнить приведенные ниже шаги.
-
Объявите и зарегистрируйте ваше перенаправленное событие с помощью системного вызова RegisterRoutedEvent.
-
Укажите стратегию маршрутизации, например Bubble, Tunnel или Direct.
-
Укажите обработчик событий.
Объявите и зарегистрируйте ваше перенаправленное событие с помощью системного вызова RegisterRoutedEvent.
Укажите стратегию маршрутизации, например Bubble, Tunnel или Direct.
Укажите обработчик событий.
Давайте рассмотрим пример, чтобы понять больше о пользовательских перенаправленных событиях. Следуйте инструкциям ниже
-
Создайте новый проект WPF с WPFCustomRoutedEvent
-
Щелкните правой кнопкой мыши ваше решение и выберите Добавить> Новый элемент …
-
Откроется следующее диалоговое окно, теперь выберите Custom Control (WPF) и назовите его MyCustomControl .
Создайте новый проект WPF с WPFCustomRoutedEvent
Щелкните правой кнопкой мыши ваше решение и выберите Добавить> Новый элемент …
Откроется следующее диалоговое окно, теперь выберите Custom Control (WPF) и назовите его MyCustomControl .
-
Нажмите кнопку Добавить , и вы увидите, что в ваше решение будут добавлены два новых файла (Themes / Generic.xaml и MyCustomControl.cs).
Нажмите кнопку Добавить , и вы увидите, что в ваше решение будут добавлены два новых файла (Themes / Generic.xaml и MyCustomControl.cs).
Следующий код XAML устанавливает стиль для пользовательского элемента управления в файле Generic.xaml.
<ResourceDictionary xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "clr-namespace:WPFCustomRoutedEvent"> <Style TargetType = "{x:Type local:MyCustomControl}"> <Setter Property = "Margin" Value = "50"/> <Setter Property = "Template"> <Setter.Value> <ControlTemplate TargetType = "{x:Type local:MyCustomControl}"> <Border Background = "{TemplateBinding Background}" BorderBrush = "{TemplateBinding BorderBrush}" BorderThickness = "{TemplateBinding BorderThickness}"> <Button x:Name = "PART_Button" Content = "Click Me" /> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
Ниже приведен код C # для класса MyCustomControl, который наследуется от класса Control, в котором для настраиваемого элемента управления создается настраиваемое перенаправленное событие Click.
using System.Windows; using System.Windows.Controls; namespace WPFCustomRoutedEvent { public class MyCustomControl : Control { static MyCustomControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl))); } public override void OnApplyTemplate() { base.OnApplyTemplate(); //demo purpose only, check for previous instances and remove the handler first var button = GetTemplateChild("PART_Button") as Button; if (button ! = null) button.Click + = Button_Click; } void Button_Click(object sender, RoutedEventArgs e) { RaiseClickEvent(); } public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyCustomControl)); public event RoutedEventHandler Click { add { AddHandler(ClickEvent, value); } remove { RemoveHandler(ClickEvent, value); } } protected virtual void RaiseClickEvent() { RoutedEventArgs args = new RoutedEventArgs(MyCustomControl.ClickEvent); RaiseEvent(args); } } }
Вот пользовательская реализация перенаправленного события в C #, которая будет отображать окно сообщения, когда пользователь щелкает по нему.
using System.Windows; namespace WPFCustomRoutedEvent { // <summary> // Interaction logic for MainWindow.xaml // </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void MyCustomControl_Click(object sender, RoutedEventArgs e) { MessageBox.Show("It is the custom routed event of your custom control"); } } }
Вот реализация в MainWindow.xaml для добавления пользовательского элемента управления с перенаправленным событием Click.
<Window x:Class = "WPFCustomRoutedEvent.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "clr-namespace:WPFCustomRoutedEvent" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <local:MyCustomControl Click = "MyCustomControl_Click" /> </Grid> </Window>
Когда приведенный выше код компилируется и выполняется, он создаст следующее окно, которое содержит пользовательский элемент управления.
Когда вы нажимаете на пользовательский элемент управления, он выдаст следующее сообщение.
WPF — Управление
Windows Presentation Foundation (WPF) позволяет разработчикам легко создавать и создавать визуально обогащенные приложения на основе пользовательского интерфейса.
-
Классические элементы пользовательского интерфейса или элементы управления в других структурах пользовательского интерфейса также улучшены в приложениях WPF.
-
Все стандартные элементы управления WPF можно найти в панели инструментов, которая является частью System.Windows.Controls.
-
Эти элементы управления также могут быть созданы на языке разметки XAML.
Классические элементы пользовательского интерфейса или элементы управления в других структурах пользовательского интерфейса также улучшены в приложениях WPF.
Все стандартные элементы управления WPF можно найти в панели инструментов, которая является частью System.Windows.Controls.
Эти элементы управления также могут быть созданы на языке разметки XAML.
Полная иерархия наследования элементов управления WPF выглядит следующим образом:
Следующая таблица содержит список элементов управления, которые мы обсудим в следующих главах.
Старший | Управление и описание |
---|---|
1 | кнопка
Элемент управления, который реагирует на ввод пользователя |
2 | Календарь
Представляет элемент управления, который позволяет пользователю выбирать дату с помощью визуального отображения календаря. |
3 | CheckBox
Элемент управления, который пользователь может выбрать или очистить. |
4 | Поле со списком
Раскрывающийся список элементов, из которых пользователь может выбрать. |
5 | Контекстное меню
Получает или задает элемент контекстного меню, который должен появляться всякий раз, когда контекстное меню запрашивается через пользовательский интерфейс (UI) из этого элемента. |
6 | DataGrid
Представляет элемент управления, который отображает данные в настраиваемой сетке. |
7 | DatePicker
Элемент управления, который позволяет пользователю выбрать дату. |
8 | Диалоги
Приложение также может отображать дополнительные окна, чтобы помочь пользователю собирать или отображать важную информацию. |
9 | Вид сетки
Элемент управления, представляющий коллекцию элементов в строках и столбцах, которые можно прокручивать по горизонтали. |
10 | Образ
Элемент управления, который представляет изображение. |
11 | этикетка
Отображает текст в форме. Обеспечивает поддержку ключей доступа. |
12 | ListBox
Элемент управления, представляющий встроенный список элементов, из которых пользователь может выбирать. |
13 | меню
Представляет элемент управления меню Windows, который позволяет иерархически организовывать элементы, связанные с командами и обработчиками событий. |
14 | PasswordBox
Элемент управления для ввода паролей. |
15 | Неожиданно возникнуть
Отображает содержимое поверх существующего содержимого в пределах окна приложения. |
16 | Индикатор
Элемент управления, который показывает прогресс, отображая панель. |
17 | Переключатель
Элемент управления, который позволяет пользователю выбрать один вариант из группы параметров. |
18 | ScrollViewer
Контейнерный элемент управления, который позволяет пользователю перемещать и масштабировать его содержимое. |
19 | ползунок
Элемент управления, позволяющий пользователю выбирать из диапазона значений путем перемещения элемента управления Thumb вдоль дорожки. |
20 | TextBlock
Элемент управления, который отображает текст. |
21 | Кнопка-переключатель
Кнопка, которую можно переключать между двумя состояниями. |
22 | ToolTip
Всплывающее окно, которое отображает информацию для элемента. |
23 | Окно
Корневое окно, которое обеспечивает параметр минимизации / максимизации, строку заголовка, границу и кнопку закрытия |
24 | Сторонние элементы управления
Используйте сторонние элементы управления в своих приложениях WPF. |
Элемент управления, который реагирует на ввод пользователя
Представляет элемент управления, который позволяет пользователю выбирать дату с помощью визуального отображения календаря.
Элемент управления, который пользователь может выбрать или очистить.
Раскрывающийся список элементов, из которых пользователь может выбрать.
Получает или задает элемент контекстного меню, который должен появляться всякий раз, когда контекстное меню запрашивается через пользовательский интерфейс (UI) из этого элемента.
Представляет элемент управления, который отображает данные в настраиваемой сетке.
Элемент управления, который позволяет пользователю выбрать дату.
Приложение также может отображать дополнительные окна, чтобы помочь пользователю собирать или отображать важную информацию.
Элемент управления, представляющий коллекцию элементов в строках и столбцах, которые можно прокручивать по горизонтали.
Элемент управления, который представляет изображение.
Отображает текст в форме. Обеспечивает поддержку ключей доступа.
Элемент управления, представляющий встроенный список элементов, из которых пользователь может выбирать.
Представляет элемент управления меню Windows, который позволяет иерархически организовывать элементы, связанные с командами и обработчиками событий.
Элемент управления для ввода паролей.
Отображает содержимое поверх существующего содержимого в пределах окна приложения.
Элемент управления, который показывает прогресс, отображая панель.
Элемент управления, который позволяет пользователю выбрать один вариант из группы параметров.
Контейнерный элемент управления, который позволяет пользователю перемещать и масштабировать его содержимое.
Элемент управления, позволяющий пользователю выбирать из диапазона значений путем перемещения элемента управления Thumb вдоль дорожки.
Элемент управления, который отображает текст.
Кнопка, которую можно переключать между двумя состояниями.
Всплывающее окно, которое отображает информацию для элемента.
Корневое окно, которое обеспечивает параметр минимизации / максимизации, строку заголовка, границу и кнопку закрытия
Используйте сторонние элементы управления в своих приложениях WPF.
Мы обсудим все эти элементы управления один за другим с их реализацией.
WPF — Макеты
Расположение элементов управления очень важно и важно для удобства использования приложения. Он используется для организации группы элементов GUI в вашем приложении. Есть некоторые важные вещи, которые следует учитывать при выборе макетов панелей —
- Позиции дочерних элементов
- Размеры дочерних элементов
- Наслаивание перекрывающихся дочерних элементов друг на друга
Фиксированное расположение элементов управления в пикселях не работает, когда приложение должно быть установлено на разных разрешениях экрана. XAML предоставляет богатый набор встроенных панелей макета для правильной организации элементов графического интерфейса. Вот некоторые из наиболее часто используемых и популярных панелей макета:
Старший | Панели и описание |
---|---|
1 | Панель стека
Панель стека — это простая и полезная панель макета в XAML. В панели стека дочерние элементы могут быть расположены в одну линию, по горизонтали или вертикали, в зависимости от свойства ориентации. |
2 | Обернуть панель
В WrapPanel дочерние элементы располагаются в последовательном порядке слева направо или сверху вниз в зависимости от свойства ориентации. |
3 | Док-панель
DockPanel определяет область для размещения дочерних элементов относительно друг друга, по горизонтали или по вертикали. С DockPanel вы можете легко закрепить дочерние элементы сверху, снизу, справа, слева и по центру, используя свойство Dock . |
4 | Панель холста
Панель «Холст» — это базовая панель макета, в которой дочерние элементы можно расположить явно, используя координаты, относящиеся к холсту с любой стороны, например слева, справа, сверху и снизу. |
5 | Сетка Панель
Grid Panel предоставляет гибкую область, которая состоит из строк и столбцов. В Grid дочерние элементы могут быть расположены в табличной форме. |
Панель стека — это простая и полезная панель макета в XAML. В панели стека дочерние элементы могут быть расположены в одну линию, по горизонтали или вертикали, в зависимости от свойства ориентации.
В WrapPanel дочерние элементы располагаются в последовательном порядке слева направо или сверху вниз в зависимости от свойства ориентации.
DockPanel определяет область для размещения дочерних элементов относительно друг друга, по горизонтали или по вертикали. С DockPanel вы можете легко закрепить дочерние элементы сверху, снизу, справа, слева и по центру, используя свойство Dock .
Панель «Холст» — это базовая панель макета, в которой дочерние элементы можно расположить явно, используя координаты, относящиеся к холсту с любой стороны, например слева, справа, сверху и снизу.
Grid Panel предоставляет гибкую область, которая состоит из строк и столбцов. В Grid дочерние элементы могут быть расположены в табличной форме.
WPF — Вложенность макета
Вложенность макета означает использование панели макета внутри другого макета, например, определение панелей стека внутри сетки. Эта концепция широко используется для использования преимуществ нескольких макетов в приложении. В следующем примере мы будем использовать панели стека внутри сетки.
Давайте посмотрим на следующий код XAML.
<Window x:Class = "WPFNestingLayouts.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:WPFNestingLayouts" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> <Grid Background = "AntiqueWhite"> <Grid.RowDefinitions> <RowDefinition Height = "*" /> <RowDefinition Height = "*" /> <RowDefinition Height = "*" /> <RowDefinition Height = "*" /> <RowDefinition Height = "*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width = "*" /> </Grid.ColumnDefinitions> <Label Content = "Employee Info" FontSize = "15" FontWeight = "Bold" Grid.Column = "0" Grid.Row = "0"/> <StackPanel Grid.Column = "0" Grid.Row = "1" Orientation = "Horizontal"> <Label Content = "Name" VerticalAlignment = "Center" Width = "70"/> <TextBox Name = "txtName" Text = "Muhammad Ali" VerticalAlignment = "Center" Width = "200"> </TextBox> </StackPanel> <StackPanel Grid.Column = "0" Grid.Row = "2" Orientation = "Horizontal"> <Label Content = "ID" VerticalAlignment = "Center" Width = "70"/> <TextBox Name = "txtCity" Text = "421" VerticalAlignment = "Center" Width = "50"> </TextBox> </StackPanel> <StackPanel Grid.Column = "0" Grid.Row = "3" Orientation = "Horizontal"> <Label Content = "Age" VerticalAlignment = "Center" Width = "70"/> <TextBox Name = "txtState" Text = "32" VerticalAlignment = "Center" Width = "50"></TextBox> </StackPanel> <StackPanel Grid.Column = "0" Grid.Row = "4" Orientation = "Horizontal"> <Label Content = "Title" VerticalAlignment = "Center" Width = "70"/> <TextBox Name = "txtCountry" Text = "Programmer" VerticalAlignment = "Center" Width = "200"></TextBox> </StackPanel> </Grid> </Window>
Когда вы скомпилируете и выполните приведенный выше код, он выдаст следующее окно.
Мы рекомендуем вам выполнить приведенный выше пример кода и попробовать другие схемы размещения.
WPF — Ввод
Windows Presentation Foundation (WPF) предоставляет мощный API, с помощью которого приложения могут получать ввод с различных устройств, таких как мышь, клавиатура и сенсорные панели. В этой главе мы обсудим следующие типы ввода, которые можно обрабатывать в приложениях WPF:
Старший | Входы и описание |
---|---|
1 | мышь
Существуют различные типы входов мыши, такие как MouseDown, MouseEnter, MouseLeave и т. Д. |
2 | клавиатура
Существует много типов клавиатурных вводов, таких как KeyDown, KeyUp, TextInput и т. Д. |
3 | ContextMenu или RoutedCommands
RoutedCommands позволяют обрабатывать ввод на более семантическом уровне. На самом деле это простые инструкции, такие как «Создать», «Открыть», «Копировать», «Вырезать» и «Сохранить». |
4 | Мультитач
Windows 7 и более поздние версии имеют возможность получать входные данные от нескольких сенсорных устройств. Приложения WPF также могут обрабатывать сенсорный ввод в качестве другого ввода, такого как мышь или клавиатура, вызывая события, когда происходит касание. |
Существуют различные типы входов мыши, такие как MouseDown, MouseEnter, MouseLeave и т. Д.
Существует много типов клавиатурных вводов, таких как KeyDown, KeyUp, TextInput и т. Д.
RoutedCommands позволяют обрабатывать ввод на более семантическом уровне. На самом деле это простые инструкции, такие как «Создать», «Открыть», «Копировать», «Вырезать» и «Сохранить».
Windows 7 и более поздние версии имеют возможность получать входные данные от нескольких сенсорных устройств. Приложения WPF также могут обрабатывать сенсорный ввод в качестве другого ввода, такого как мышь или клавиатура, вызывая события, когда происходит касание.
WPF — Командная строка
Аргумент командной строки — это механизм, в котором пользователь может передать набор параметров или значений в приложение WPF при его выполнении. Эти аргументы очень важны для управления приложением извне, например, если вы хотите открыть документ Word из командной строки, вы можете использовать эту команду « C: \> start winword word1.docx », и она откроет word1 .docx документ.
Аргументы командной строки обрабатываются в функции запуска. Ниже приведен простой пример, который показывает, как передавать аргументы командной строки в приложение WPF. Давайте создадим новое приложение WPF с именем WPFCommandLine .
-
Перетащите одно текстовое поле с панели инструментов в окно дизайна.
-
В этом примере мы передадим путь txt-файла нашему приложению в качестве параметра командной строки.
-
Программа прочитает текстовый файл, а затем запишет весь текст в текстовое поле.
-
Следующий код XAML создает текстовое поле и инициализирует его с некоторыми свойствами.
Перетащите одно текстовое поле с панели инструментов в окно дизайна.
В этом примере мы передадим путь txt-файла нашему приложению в качестве параметра командной строки.
Программа прочитает текстовый файл, а затем запишет весь текст в текстовое поле.
Следующий код XAML создает текстовое поле и инициализирует его с некоторыми свойствами.
<Window x:Class = "WPFCommandLine.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:WPFCommandLine" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> <Grid> <TextBox x:Name = "textBox" HorizontalAlignment = "Left" Height = "180" Margin = "100" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "300"/> </Grid> </Window>
- Теперь подпишите событие Startup в файле App.xaml, как показано ниже.
<Application x:Class = "WPFCommandLine.App" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "clr-namespace:WPFCommandLine" StartupUri = "MainWindow.xaml" Startup = "app_Startup"> <Application.Resources> </Application.Resources> </Application>
-
Ниже приведена реализация события app_Startup в App.xaml.cs, которое получит аргументы командной строки.
Ниже приведена реализация события app_Startup в App.xaml.cs, которое получит аргументы командной строки.
using System.Windows; namespace WPFCommandLine { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : Application { public static string[] Args; void app_Startup(object sender, StartupEventArgs e) { // If no command line arguments were provided, don't process them if (e.Args.Length == 0) return; if (e.Args.Length > 0) { Args = e.Args; } } } }
-
Теперь в классе MainWindow программа откроет текстовый файл и запишет весь текст в текстовое поле.
-
Если обнаружена какая-либо ошибка, программа отобразит сообщение об ошибке в текстовом поле.
Теперь в классе MainWindow программа откроет текстовый файл и запишет весь текст в текстовое поле.
Если обнаружена какая-либо ошибка, программа отобразит сообщение об ошибке в текстовом поле.
using System; using System.IO; using System.Windows; namespace WPFCommandLine { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); String[] args = App.Args; try { // Open the text file using a stream reader. using (StreamReader sr = new StreamReader(args[0])) { // Read the stream to a string, and write // the string to the text box String line = sr.ReadToEnd(); textBox.AppendText(line.ToString()); textBox.AppendText("\n"); } } catch (Exception e) { textBox.AppendText("The file could not be read:"); textBox.AppendText("\n"); textBox.AppendText(e.Message); } } } }
-
Когда приведенный выше код скомпилирован и выполнен, он создаст пустое окно с текстовым полем, потому что эта программа нуждается в аргументе командной строки. Таким образом, Visual Studio предоставляет простой способ выполнить ваше приложение с параметрами командной строки.
-
Щелкните правой кнопкой мыши ваш проект WPF в обозревателе решений и выберите свойства, появится следующее окно.
Когда приведенный выше код скомпилирован и выполнен, он создаст пустое окно с текстовым полем, потому что эта программа нуждается в аргументе командной строки. Таким образом, Visual Studio предоставляет простой способ выполнить ваше приложение с параметрами командной строки.
Щелкните правой кнопкой мыши ваш проект WPF в обозревателе решений и выберите свойства, появится следующее окно.
-
Выберите опцию Debug и напишите путь к файлу в аргументе командной строки.
-
Создайте текстовый файл с Test.txt, напишите в нем какой-нибудь текст и сохраните его в любом месте. В этом случае текстовый файл сохраняется на жестком диске « D: \ ».
-
Сохраните изменения в вашем проекте, скомпилируйте и запустите приложение сейчас. Вы увидите текст в TextBox, который программа читает из файла Text.txt.
Выберите опцию Debug и напишите путь к файлу в аргументе командной строки.
Создайте текстовый файл с Test.txt, напишите в нем какой-нибудь текст и сохраните его в любом месте. В этом случае текстовый файл сохраняется на жестком диске « D: \ ».
Сохраните изменения в вашем проекте, скомпилируйте и запустите приложение сейчас. Вы увидите текст в TextBox, который программа читает из файла Text.txt.
Теперь давайте попробуем изменить имя файла на вашем компьютере с Test.txt на Test1.txt и снова запустить вашу программу, затем вы увидите это сообщение об ошибке в текстовом поле.
Мы рекомендуем вам выполнить приведенный выше код и выполнить все шаги для успешного выполнения вашего приложения.
WPF — привязка данных
Привязка данных — это механизм в приложениях WPF, который обеспечивает простой и легкий способ для приложений Windows Runtime отображать и взаимодействовать с данными. В этом механизме управление данными полностью отделено от способа передачи данных.
Привязка данных обеспечивает поток данных между элементами пользовательского интерфейса и объектом данных в пользовательском интерфейсе. Когда привязка установлена и данные или ваша бизнес-модель изменяются, она автоматически отражает обновления элементов пользовательского интерфейса и наоборот. Также возможно связать не со стандартным источником данных, а с другим элементом на странице.
Привязка данных бывает двух типов — односторонняя привязка данных и двусторонняя привязка данных .
Одностороннее связывание данных
При одностороннем связывании данные привязываются от своего источника (то есть объекта, который содержит данные) к своей цели (то есть объекту, который отображает данные)
-
Давайте рассмотрим простой пример, чтобы лучше понять одностороннюю привязку данных. Прежде всего, создайте новый проект WPF с именем WPFDataBinding .
-
Следующий код XAML создает две метки, два текстовых поля и одну кнопку и инициализирует их с некоторыми свойствами.
Давайте рассмотрим простой пример, чтобы лучше понять одностороннюю привязку данных. Прежде всего, создайте новый проект WPF с именем WPFDataBinding .
Следующий код XAML создает две метки, два текстовых поля и одну кнопку и инициализирует их с некоторыми свойствами.
<Window x:Class = "WPFDataBinding.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:WPFDataBinding" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <Grid.RowDefinitions> <RowDefinition Height = "Auto" /> <RowDefinition Height = "Auto" /> <RowDefinition Height = "*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width = "Auto" /> <ColumnDefinition Width = "200" /> </Grid.ColumnDefinitions> <Label Name = "nameLabel" Margin = "2">_Name:</Label> <TextBox Name = "nameText" Grid.Column = "1" Margin = "2" Text = "{Binding Name, Mode = OneWay}"/> <Label Name = "ageLabel" Margin = "2" Grid.Row = "1">_Age:</Label> <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "2" Text = "{Binding Age, Mode = OneWay}"/> <StackPanel Grid.Row = "2" Grid.ColumnSpan = "2"> <Button Content = "_Show..." Click="Button_Click" /> </StackPanel> </Grid> </Window>
-
Текстовые свойства обоих текстовых полей привязываются к «Имени» и «Возрасту», которые являются переменными класса класса «Человек», как показано ниже.
-
В классе Person у нас есть только две переменные Name и Age , и его объект инициализируется в классе MainWindow .
-
В коде XAML мы связываемся со свойством Name и Age, но мы не выбрали, к какому объекту принадлежит это свойство.
-
Более простой способ — назначить объект DataContext , свойства которого мы связываем в следующем коде C # в MainWindowconstructor .
Текстовые свойства обоих текстовых полей привязываются к «Имени» и «Возрасту», которые являются переменными класса класса «Человек», как показано ниже.
В классе Person у нас есть только две переменные Name и Age , и его объект инициализируется в классе MainWindow .
В коде XAML мы связываемся со свойством Name и Age, но мы не выбрали, к какому объекту принадлежит это свойство.
Более простой способ — назначить объект DataContext , свойства которого мы связываем в следующем коде C # в MainWindowconstructor .
using System.Windows; namespace WPFDataBinding { public partial class MainWindow : Window { Person person = new Person { Name = "Salman", Age = 26 }; public MainWindow() { InitializeComponent(); this.DataContext = person; } private void Button_Click(object sender, RoutedEventArgs e) { string message = person.Name + " is " + person.Age; MessageBox.Show(message); } } public class Person { private string nameValue; public string Name { get { return nameValue; } set { nameValue = value; } } private double ageValue; public double Age { get { return ageValue; } set { if (value != ageValue) { ageValue = value; } } } } }
-
Давайте запустим это приложение, и вы сразу увидите в нашем MainWindow, что мы успешно связались с именем и возрастом этого объекта Person.
Давайте запустим это приложение, и вы сразу увидите в нашем MainWindow, что мы успешно связались с именем и возрастом этого объекта Person.
Когда вы нажимаете кнопку « Показать» , в окне сообщения отображаются имя и возраст.
Давайте изменим Имя и Возраст в диалоговом окне.
Если вы сейчас нажмете кнопку «Показать», то снова появится то же сообщение.
Это связано с тем, что режим привязки данных установлен в одностороннем порядке в коде XAML. Чтобы показать обновленные данные, вам необходимо понять двустороннюю привязку данных.
Двухстороннее связывание данных
При двусторонней привязке пользователь может изменять данные через пользовательский интерфейс и обновлять эти данные в источнике. Если источник изменяется, когда пользователь просматривает представление, вы хотите, чтобы представление было обновлено.
Давайте возьмем тот же пример, но здесь мы изменим режим привязки с Одностороннего на Двусторонний в коде XAML.
<Window x:Class = "WPFDataBinding.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:WPFDataBinding" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <Grid.RowDefinitions> <RowDefinition Height = "Auto" /> <RowDefinition Height = "Auto" /> <RowDefinition Height = "*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width = "Auto" /> <ColumnDefinition Width = "200" /> </Grid.ColumnDefinitions> <Label Name = "nameLabel" Margin = "2">_Name:</Label> <TextBox Name = "nameText" Grid.Column = "1" Margin = "2" Text = "{Binding Name, Mode = TwoWay}"/> <Label Name = "ageLabel" Margin = "2" Grid.Row = "1">_Age:</Label> <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "2" Text = "{Binding Age, Mode = TwoWay}"/> <StackPanel Grid.Row = "2" Grid.ColumnSpan = "2"> <Button Content = "_Show..." Click = "Button_Click" /> </StackPanel> </Grid> </Window>
Давайте снова запустим это приложение.
Это даст тот же результат —
Давайте теперь изменим значения имени и возраста —
Если вы нажмете кнопку «Показать сейчас», отобразится обновленное сообщение.
Мы рекомендуем вам выполнить приведенный выше код в обоих случаях для лучшего понимания концепции.
WPF — Ресурсы
Ресурсы — это обычно определения, связанные с каким-либо объектом, который вы просто планируете использовать чаще, чем один раз. Это возможность хранить данные локально для элементов управления или для текущего окна или глобально для всех приложений.
Определение объекта как ресурса позволяет нам получить к нему доступ из другого места. Это означает, что объект можно использовать повторно. Ресурсы определяются в словарях ресурсов, и любой объект может быть определен как ресурс, эффективно делающий его разделяемым активом. Уникальный ключ указывается для ресурса XAML, и на него можно ссылаться, используя расширение разметки StaticResource.
Ресурсы могут быть двух типов —
- StaticResource
- DynamicResource
StaticResource является одноразовым поиском, тогда как DynamicResource работает больше как привязка данных. Он помнит, что свойство связано с определенным ключом ресурса. Если объект, связанный с этим ключом, изменится, динамический ресурс обновит целевое свойство.
пример
Вот простое приложение для ресурса SolidColorBrush.
-
Давайте создадим новый проект WPF с именем WPFResouces .
-
Перетащите два прямоугольника и установите их свойства, как показано в следующем коде XAML.
Давайте создадим новый проект WPF с именем WPFResouces .
Перетащите два прямоугольника и установите их свойства, как показано в следующем коде XAML.
<Window x:Class = "WPFResources.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:WPFResources" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> <Window.Resources> <SolidColorBrush x:Key = "brushResource" Color = "Blue" /> </Window.Resources> <StackPanel> <Rectangle Height = "50" Margin = "20" Fill = "{StaticResource brushResource}" /> <Rectangle Height = "50" Margin = "20" Fill = "{DynamicResource brushResource}" /> <Button x:Name = "changeResourceButton" Content = "_Change Resource" Click = "changeResourceButton_Click" /> </StackPanel> </Window>
-
В приведенном выше коде XAML вы можете видеть, что один прямоугольник имеет StaticResource, а другой — DynamicResource, а цвет brushResource — Bisque.
-
Когда вы скомпилируете и выполните код, он создаст следующее MainWindow.
В приведенном выше коде XAML вы можете видеть, что один прямоугольник имеет StaticResource, а другой — DynamicResource, а цвет brushResource — Bisque.
Когда вы скомпилируете и выполните код, он создаст следующее MainWindow.
Когда вы нажмете кнопку «Изменить ресурс», вы увидите, что прямоугольник с DynamicResource изменит свой цвет на красный.
Объем ресурса
Ресурсы определяются в словарях ресурсов , но существует множество мест, где можно определить словарь ресурсов. В приведенном выше примере словарь ресурсов определен на уровне окна / страницы. В каком словаре определяется ресурс, немедленно ограничивается область действия этого ресурса. Таким образом, область действия, т. Е. Где вы можете использовать ресурс, зависит от того, где вы его определили.
-
Определите ресурс в словаре ресурсов сетки, и он будет доступен только этой сетке и ее дочерним элементам.
-
Определите его в окне / странице, и он будет доступен для всех элементов в этом окне / странице.
-
Корень приложения можно найти в словаре ресурсов App.xaml. Это корень нашего приложения, поэтому ресурсы, определенные здесь, относятся ко всему приложению.
Определите ресурс в словаре ресурсов сетки, и он будет доступен только этой сетке и ее дочерним элементам.
Определите его в окне / странице, и он будет доступен для всех элементов в этом окне / странице.
Корень приложения можно найти в словаре ресурсов App.xaml. Это корень нашего приложения, поэтому ресурсы, определенные здесь, относятся ко всему приложению.
Что касается области действия ресурса, наиболее часто это уровень приложения, уровень страницы и определенный уровень элемента, такой как Grid, StackPanel и т. Д.
Приведенное выше приложение имеет ресурсы на уровне окна / страницы.
Ресурсные словари
Словари ресурсов в приложениях XAML подразумевают, что словари ресурсов хранятся в отдельных файлах. Это следует почти во всех приложениях XAML. Определение ресурсов в отдельных файлах может иметь следующие преимущества:
-
Разделение между определением ресурсов в словаре ресурсов и кодом, связанным с пользовательским интерфейсом.
-
Определение всех ресурсов в отдельном файле, таком как App.xaml, сделает их доступными во всем приложении.
Разделение между определением ресурсов в словаре ресурсов и кодом, связанным с пользовательским интерфейсом.
Определение всех ресурсов в отдельном файле, таком как App.xaml, сделает их доступными во всем приложении.
Итак, как мы определяем наши ресурсы в словаре ресурсов в отдельном файле? Что ж, это очень просто, просто добавьте новый словарь ресурсов через Visual Studio, выполнив следующие шаги:
-
В вашем решении добавьте новую папку и назовите ее ResourceDictionaries .
-
Щелкните правой кнопкой мыши на этой папке и выберите Resource Dictionary из пункта «Добавить подменю» и назовите его DictionaryWithBrush.xaml
В вашем решении добавьте новую папку и назовите ее ResourceDictionaries .
Щелкните правой кнопкой мыши на этой папке и выберите Resource Dictionary из пункта «Добавить подменю» и назовите его DictionaryWithBrush.xaml
пример
Давайте теперь возьмем тот же пример, но здесь мы определим словарь ресурсов на уровне приложения. Код XAML для MainWindow.xaml выглядит следующим образом:
<Window x:Class = "WPFResources.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:WPFResources" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> <StackPanel> <Rectangle Height = "50" Margin = "20" Fill = "{StaticResource brushResource}" /> <Rectangle Height = "50" Margin = "20" Fill = "{DynamicResource brushResource}" /> <Button x:Name = "changeResourceButton" Content = "_Change Resource" Click = "changeResourceButton_Click" /> </StackPanel> </Window>
Вот реализация в DictionaryWithBrush.xaml —
<ResourceDictionary xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"> <SolidColorBrush x:Key = "brushResource" Color = "Blue" /> </ResourceDictionary>
Вот реализация в app.xaml —
<Application x:Class="WPFResources.App" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" StartupUri = "MainWindow.xaml"> <Application.Resources> <ResourceDictionary Source = " XAMLResources\ResourceDictionaries\DictionaryWithBrush.xaml"/> </Application.Resources> </Application>
Когда приведенный выше код скомпилирован и выполнен, он выдаст следующий вывод:
Когда вы нажмете кнопку «Изменить ресурс», прямоугольник изменит свой цвет на красный.
Мы рекомендуем вам выполнить приведенный выше код и попробовать еще несколько ресурсов (например, цвет фона).
WPF — Шаблоны
Шаблон описывает общий вид и внешний вид элемента управления. Для каждого элемента управления есть шаблон по умолчанию, связанный с ним, который дает элементу вид его. В приложениях WPF вы можете легко создавать свои собственные шаблоны, когда вы хотите настроить визуальное поведение и внешний вид элемента управления.
Связь между логикой и шаблоном может быть достигнута путем привязки данных. Основные различия между стилями и шаблонами перечислены ниже —
-
Стили могут изменять внешний вид вашего элемента управления только с помощью свойств этого элемента по умолчанию.
-
С помощью шаблонов вы можете получить доступ к большему количеству частей элемента управления, чем к стилям. Вы также можете указать как существующее, так и новое поведение элемента управления.
Стили могут изменять внешний вид вашего элемента управления только с помощью свойств этого элемента по умолчанию.
С помощью шаблонов вы можете получить доступ к большему количеству частей элемента управления, чем к стилям. Вы также можете указать как существующее, так и новое поведение элемента управления.
Есть два типа шаблонов, которые наиболее часто используются —
- Шаблон управления
- Шаблон данных
Шаблон управления
Шаблон элемента управления определяет внешний вид элемента управления. Все элементы пользовательского интерфейса имеют внешний вид и поведение, например, кнопка имеет внешний вид и поведение. Событие щелчка или событие наведения мыши — это поведение, которое запускается в ответ на щелчок и наведение, а также имеется внешний вид кнопки по умолчанию, который можно изменить с помощью шаблона элемента управления.
пример
Давайте рассмотрим простой пример. Мы создадим две кнопки (одна с шаблоном, а другая кнопка по умолчанию) и инициализируем их некоторыми свойствами.
<Window x:Class = "TemplateDemo.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> <Window.Resources> <ControlTemplate x:Key = "ButtonTemplate" TargetType = "Button"> <Grid> <Ellipse x:Name = "ButtonEllipse" Height = "100" Width = "150" > <Ellipse.Fill> <LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4"> <GradientStop Offset = "0" Color = "Red" /> <GradientStop Offset = "1" Color = "Orange" /> </LinearGradientBrush> </Ellipse.Fill> </Ellipse> <ContentPresenter Content = "{TemplateBinding Content}" HorizontalAlignment = "Center" VerticalAlignment = "Center" /> </Grid> <ControlTemplate.Triggers> <Trigger Property = "IsMouseOver" Value = "True"> <Setter TargetName = "ButtonEllipse" Property = "Fill" > <Setter.Value> <LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4"> <GradientStop Offset = "0" Color = "YellowGreen" /> <GradientStop Offset = "1" Color = "Gold" /> </LinearGradientBrush> </Setter.Value> </Setter> </Trigger> <Trigger Property = "IsPressed" Value = "True"> <Setter Property = "RenderTransform"> <Setter.Value> <ScaleTransform ScaleX = "0.8" ScaleY = "0.8" CenterX = "0" CenterY = "0" /> </Setter.Value> </Setter> <Setter Property = "RenderTransformOrigin" Value = "0.5,0.5" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Window.Resources> <StackPanel> <Button Content = "Round Button!" Template = "{StaticResource ButtonTemplate}" Width = "150" Margin = "50" /> <Button Content = "Default Button!" Height = "40" Width = "150" Margin = "5" /> </StackPanel> </Window>
Когда вы скомпилируете и выполните приведенный выше код, он отобразит следующее MainWindow.
Когда вы наводите курсор мыши на кнопку с пользовательским шаблоном, он изменит свой цвет, как показано ниже.
Шаблон данных
Шаблон данных определяет и определяет внешний вид и структуру коллекции данных. Это обеспечивает гибкость для форматирования и определения представления данных на любом элементе пользовательского интерфейса. В основном он используется в элементах управления, связанных с данными, таких как ComboBox, ListBox и т. Д.
пример
-
Давайте рассмотрим простой пример, чтобы понять концепцию шаблона данных. Создайте новый проект WPF с именем WPFDataTemplates .
-
В следующем коде XAML мы создадим шаблон данных как ресурс для хранения меток и текстовых полей. Также есть кнопка и список для отображения данных.
Давайте рассмотрим простой пример, чтобы понять концепцию шаблона данных. Создайте новый проект WPF с именем WPFDataTemplates .
В следующем коде XAML мы создадим шаблон данных как ресурс для хранения меток и текстовых полей. Также есть кнопка и список для отображения данных.
<Window x:Class = "WPFDataTemplates.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:WPFDataTemplates" xmlns:loc = "clr-namespace:WPFDataTemplates" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> <Window.Resources> <DataTemplate DataType = "{x:Type loc:Person}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height = "Auto" /> <RowDefinition Height = "Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width = "Auto" /> <ColumnDefinition Width = "200" /> </Grid.ColumnDefinitions> <Label Name = "nameLabel" Margin = "10"/> <TextBox Name = "nameText" Grid.Column = "1" Margin = "10" Text = "{Binding Name}"/> <Label Name = "ageLabel" Margin = "10" Grid.Row = "1"/> <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "10" Text = "{Binding Age}"/> </Grid> </DataTemplate> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height = "Auto" /> <RowDefinition Height = "*" /> </Grid.RowDefinitions> <ListBox ItemsSource = "{Binding}" /> <StackPanel Grid.Row = "1" > <Button Content = "_Show..." Click = "Button_Click" Width = "80" HorizontalAlignment = "Left" Margin = "10"/> </StackPanel> </Grid> </Window>
Вот реализация в C #, в которой список объектов Person присваивается DataContext, реализация класса Person и событие нажатия кнопки.
using System.Collections.Generic; using System.Windows; namespace WPFDataTemplates { public partial class MainWindow : Window { Person src = new Person { Name = "Ali", Age = 27 }; List<Person> people = new List<Person>(); public MainWindow() { InitializeComponent(); people.Add(src); people.Add(new Person { Name = "Mike", Age = 62 }); people.Add(new Person { Name = "Brian", Age = 12 }); this.DataContext = people; } private void Button_Click(object sender, RoutedEventArgs e) { string message = src.Name + " is " + src.Age; MessageBox.Show(message); } } public class Person { private string nameValue; public string Name { get { return nameValue; } set { nameValue = value; } } private double ageValue; public double Age { get { return ageValue; } set { if (value != ageValue) { ageValue = value; } } } } }
Когда вы скомпилируете и выполните приведенный выше код, он выдаст следующее окно. Он содержит один список, а внутри списка каждый элемент списка содержит данные объекта класса Person, которые отображаются в полях Метки и Текст.
WPF — Стили
.NET Framework предоставляет несколько стратегий для персонализации и настройки внешнего вида приложения. Стили предоставляют нам гибкость для установки некоторых свойств объекта и повторного использования этих конкретных настроек для нескольких объектов для единообразного внешнего вида.
-
В стилях вы можете установить только существующие свойства объекта, такие как Высота, Ширина, Размер шрифта и т. Д.
-
Может быть указано только поведение элемента управления по умолчанию.
-
Несколько свойств могут быть добавлены в одном стиле.
В стилях вы можете установить только существующие свойства объекта, такие как Высота, Ширина, Размер шрифта и т. Д.
Может быть указано только поведение элемента управления по умолчанию.
Несколько свойств могут быть добавлены в одном стиле.
Стили используются для придания единообразного вида или внешнего вида для набора элементов управления. Неявные стили используются для применения внешнего вида ко всем элементам управления данного типа и упрощения приложения. Представьте себе три кнопки, все они должны выглядеть одинаково, одинаковой ширины и высоты, одинакового размера шрифта, одинакового цвета переднего плана и т. Д. Мы можем установить все эти свойства для самих элементов кнопки, и это все еще хорошо для всех кнопок. Посмотрите на следующую диаграмму.
Но в реальных приложениях у вас, как правило, гораздо больше таких, которые должны выглядеть точно так же. И не только кнопки, конечно, вы обычно хотите, чтобы ваши текстовые блоки, текстовые поля, комбинированные блоки и т. Д. Выглядели одинаково во всем приложении. Конечно, должен быть лучший способ достигнуть этого, и это известно как моделирование . Вы можете думать о стиле как об удобном способе применения набора значений свойств для нескольких элементов. Посмотрите на следующую диаграмму.
пример
Давайте рассмотрим простой пример, чтобы понять эту концепцию. Начните с создания нового проекта WPF.
-
Перетащите три кнопки из панели инструментов в окно дизайна.
-
Следующий код XAML создает три кнопки и инициализирует их с некоторыми свойствами.
Перетащите три кнопки из панели инструментов в окно дизайна.
Следующий код XAML создает три кнопки и инициализирует их с некоторыми свойствами.
<Window x:Class = "WPFStyle.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: WPFStyle" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> <StackPanel> <Button Content = "Button1" Height = "30" Width = "80" Foreground = "Blue" FontSize = "12" Margin = "10"/> <Button Content = "Button2" Height = "30" Width = "80" Foreground = "Blue" FontSize = "12" Margin = "10"/> <Button Content = "Button3" Height = "30" Width = "80" Foreground = "Blue" FontSize = "12" Margin = "10"/> </StackPanel> </Window>
Если вы посмотрите на приведенный выше код, вы увидите, что для всех кнопок высота, ширина, цвет переднего плана, размер шрифта и свойства полей одинаковы. Теперь, когда приведенный выше код скомпилирован и выполнен, появится следующее окно.
Теперь давайте посмотрим на тот же пример, но на этот раз мы будем использовать стиль .
<Window x:Class = "XAMLStyle.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:XAMLStyle" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> <Window.Resources> <Style x:Key = "myButtonStyle" TargetType = "Button"> <Setter Property = "Height" Value = "30" /> <Setter Property = "Width" Value = "80" /> <Setter Property = "Foreground" Value = "Blue" /> <Setter Property = "FontSize" Value = "12" /> <Setter Property = "Margin" Value = "10" /> </Style> </Window.Resources> <StackPanel> <Button Content = "Button1" Style = "{StaticResource myButtonStyle}" /> <Button Content = "Button2" Style = "{StaticResource myButtonStyle}" /> <Button Content = "Button3" Style="{StaticResource myButtonStyle}" /> </StackPanel> </Window>
Стили определены в словаре ресурсов, и каждый стиль имеет уникальный идентификатор ключа и целевой тип. Внутри <style> вы можете видеть, что для каждого свойства, которое будет включено в стиль, определено несколько тегов сеттера.
В приведенном выше примере все общие свойства каждой кнопки теперь определены в стиле, а затем стиль присваивается каждой кнопке с уникальным ключом путем установки свойства style через расширение разметки StaticResource.
Когда вы скомпилируете и выполните приведенный выше код, он отобразит следующее окно (тот же вывод).
Преимущество такого подхода сразу же очевидно, мы можем использовать этот стиль в любом месте; и если нам нужно изменить его, мы просто изменим его один раз в определении стиля вместо каждого элемента.
На каком уровне определяется стиль, он мгновенно ограничивает область применения этого стиля. Таким образом, область действия, то есть где вы можете использовать стиль, зависит от того, где вы его определили. Стили могут быть определены на следующих уровнях —
Sr.No | Уровни и описание |
---|---|
1 | Уровень управления
Определение стиля на уровне элемента управления может быть применено только к этому конкретному элементу управления. Ниже приведен пример уровня управления, где кнопка и TextBlock имеют свой собственный стиль. |
2 | Уровень раскладки
Определение стиля на любом уровне макета сделает его доступным только для этого макета и его дочерних элементов. |
3 | Уровень окна
Определение стиля на уровне окна может сделать его доступным для всех элементов этого окна. |
4 | Уровень применения
Определение стиля на уровне приложения может сделать его доступным для всего приложения. Давайте возьмем тот же пример, но здесь мы поместим стили в файл app.xaml, чтобы сделать его доступным для всего приложения. |
Определение стиля на уровне элемента управления может быть применено только к этому конкретному элементу управления. Ниже приведен пример уровня управления, где кнопка и TextBlock имеют свой собственный стиль.
Определение стиля на любом уровне макета сделает его доступным только для этого макета и его дочерних элементов.
Определение стиля на уровне окна может сделать его доступным для всех элементов этого окна.
Определение стиля на уровне приложения может сделать его доступным для всего приложения. Давайте возьмем тот же пример, но здесь мы поместим стили в файл app.xaml, чтобы сделать его доступным для всего приложения.
WPF — Триггеры
Триггер в основном позволяет вам изменять значения свойств или предпринимать действия в зависимости от значения свойства. Таким образом, он позволяет вам динамически изменять внешний вид и / или поведение вашего элемента управления, не создавая новый.
Триггеры используются для изменения значения любого данного свойства, когда выполняются определенные условия. Триггеры обычно определяются в стиле или в корне документа, которые применяются к этому конкретному элементу управления. Есть три типа триггеров —
- Триггеры собственности
- Триггеры данных
- Триггеры событий
Триггеры собственности
В триггерах свойств, когда изменение происходит в одном свойстве, оно приводит к немедленному или анимированному изменению другого свойства. Например, вы можете использовать триггер свойства, чтобы изменить внешний вид кнопки, когда указатель мыши находится над кнопкой.
В следующем примере кода показано, как изменить цвет переднего плана кнопки при наведении курсора мыши на кнопку.
<Window x:Class = "WPFPropertyTriggers.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> <Window.Resources> <Style x:Key = "TriggerStyle" TargetType = "Button"> <Setter Property = "Foreground" Value = "Blue" /> <Style.Triggers> <Trigger Property = "IsMouseOver" Value = "True"> <Setter Property = "Foreground" Value = "Green" /> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Grid> <Button Width = "100" Height = "70" Style = "{StaticResource TriggerStyle}" Content = "Trigger"/> </Grid> </Window>
Когда вы скомпилируете и выполните приведенный выше код, он выдаст следующее окно —
Когда мышь наводит курсор на кнопку, ее цвет переднего плана изменится на зеленый.
Триггеры данных
Триггер данных выполняет некоторые действия, когда связанные данные удовлетворяют некоторым условиям. Давайте посмотрим на следующий код XAML, в котором флажок и текстовый блок создаются с некоторыми свойствами. Когда флажок установлен, он меняет цвет переднего плана на красный.
<Window x:Class = "WPFDataTrigger.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "Data Trigger" Height = "350" Width = "604"> <StackPanel HorizontalAlignment = "Center"> <CheckBox x:Name = "redColorCheckBox" Content = "Set red as foreground color" Margin = "20"/> <TextBlock Name = "txtblock" VerticalAlignment = "Center" Text = "Event Trigger" FontSize = "24" Margin = "20"> <TextBlock.Style> <Style> <Style.Triggers> <DataTrigger Binding = "{Binding ElementName = redColorCheckBox, Path = IsChecked}" Value = "true"> <Setter Property = "TextBlock.Foreground" Value = "Red"/> <Setter Property = "TextBlock.Cursor" Value = "Hand" /> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock> </StackPanel> </Window>
Когда приведенный выше код скомпилирован и выполнен, он выдаст следующий вывод:
Когда вы установите флажок, текстовый блок изменит цвет переднего плана на красный.
Триггеры событий
Триггер события выполняет некоторые действия при срабатывании определенного события. Обычно используется для выполнения некоторой анимации на элементе управления, такой как DoubleAnumatio, ColorAnimation и т. Д. В следующем примере мы создадим простую кнопку. Когда событие click срабатывает, оно увеличивает ширину и высоту кнопки.
<Window x:Class = "WPFEventTrigger.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <Button Content = "Click Me" Width = "60" Height = "30"> <Button.Triggers> <EventTrigger RoutedEvent = "Button.Click"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "Width" Duration = "0:0:4"> <LinearDoubleKeyFrame Value = "60" KeyTime = "0:0:0"/> <LinearDoubleKeyFrame Value = "120" KeyTime = "0:0:1"/> <LinearDoubleKeyFrame Value = "200" KeyTime = "0:0:2"/> <LinearDoubleKeyFrame Value = "300" KeyTime = "0:0:3"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "Height" Duration = "0:0:4"> <LinearDoubleKeyFrame Value = "30" KeyTime = "0:0:0"/> <LinearDoubleKeyFrame Value = "40" KeyTime = "0:0:1"/> <LinearDoubleKeyFrame Value = "80" KeyTime = "0:0:2"/> <LinearDoubleKeyFrame Value = "150" KeyTime = "0:0:3"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Button.Triggers> </Button> </Grid> </Window>
Когда вы скомпилируете и выполните приведенный выше код, он выдаст следующее окно —
Нажав на кнопку, вы увидите, что она начнет расширяться в обоих измерениях.
Мы рекомендуем вам скомпилировать и выполнить приведенные выше примеры, а также применить триггеры к другим свойствам.
WPF — отладка
Это систематический механизм выявления и исправления ошибок или дефектов в фрагменте кода, которые ведут себя не так, как вы ожидаете. Отладка сложного приложения, в котором подсистемы тесно связаны, не так проста, поскольку исправление ошибок в одной подсистеме может создавать ошибки в другой подсистеме.
Отладка в C #
В приложениях WPF программисты работают с двумя языками, такими как C # и XAML. Если вы знакомы с отладкой на любом процедурном языке, таком как C # или C / C ++, и знаете, как использовать точки останова, вы можете легко отладить часть C # своего приложения.
Давайте рассмотрим простой пример, чтобы продемонстрировать, как отлаживать код на C #. Создайте новый проект WPF с именем WPFDebuggingDemo . Перетащите четыре метки, три текстовых поля и одну кнопку из панели инструментов. Посмотрите на следующий код XAML.
<Window x:Class = "WPFDebuggingDemo.Window1" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "Window1" Height = "400" Width = "604"> <Grid> <TextBox Height = "23" Margin = "0,44,169,0" Name = "textBox1" VerticalAlignment = "Top" HorizontalAlignment = "Right" Width = "120" /> <TextBox Height = "23" Margin = "0,99,169,0" Name = "textBox2" VerticalAlignment = "Top" HorizontalAlignment = "Right" Width = "120" /> <TextBox HorizontalAlignment = "Right" Margin = "0,153,169,0" Name = "textBox3" Width = "120" Height = "23" VerticalAlignment = "Top" /> <Label Height = "28" Margin = "117,42,0,0" Name = "label1" VerticalAlignment = "Top" HorizontalAlignment = "Left" Width = "120"> Item 1</Label> <Label Height = "28" HorizontalAlignment = "Left" Margin = "117,99,0,0" Name = "label2" VerticalAlignment = "Top" Width = "120"> Item 2</Label> <Label HorizontalAlignment = "Left" Margin = "117,153,0,181" Name = "label3" Width = "120">Item 3</Label> <Button Height = "23" HorizontalAlignment = "Right" Margin = "0,0,214,127" Name = "button1" VerticalAlignment = "Bottom" Width = "75" Click = "button1_Click">Total</Button> <Label Height = "28" HorizontalAlignment = "Right" Margin = "0,0,169,66" Name = "label4" VerticalAlignment = "Bottom" Width = "120"/> </Grid> </Window>
Ниже приведен код C #, в котором реализовано событие нажатия кнопки.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WPFDebuggingDemo { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { if (textBox1.Text.Length > 0 && textBox2.Text.Length > 0 && textBox2.Text.Length > 0) { double total = Convert.ToDouble(textBox1.Text) + Convert.ToDouble(textBox2.Text) + Convert.ToDouble(textBox3.Text); label4.Content = total.ToString(); } else { MessageBox.Show("Enter the value in all field."); } } } }
Когда вы скомпилируете и выполните приведенный выше код, он выдаст следующее окно. Теперь введите значения в текстовые поля и нажмите кнопку Всего. Вы получите итоговое значение после суммирования всех значений, введенных в текстовые поля.
Если вы попытаетесь ввести значения, отличные от реальных, то указанное выше приложение будет аварийно завершено. Чтобы найти и устранить проблему (почему происходит сбой), вы можете вставить точки останова в событие нажатия кнопки.
Давайте напишем «abc» в пункте 1, как показано ниже.
Нажав кнопку «Итого», вы увидите, что программа останавливается в точке останова.
Теперь переместите курсор в направлении textbox1.Text, и вы увидите, что программа пытается добавить значение abc с другими значениями, поэтому программа аварийно завершает работу.
Отладка в XAML
Если вы ожидаете такой же отладки в XAML, вы будете удивлены, узнав, что пока невозможно отладить код XAML, как отладку любого другого кода процедурного языка. Когда вы слышите термин «отладка» в коде XAML, это означает, что попробуйте найти ошибку.
-
При связывании данных ваши данные не отображаются на экране, и вы не знаете, почему
-
Или проблема связана со сложными макетами.
-
Или проблема выравнивания или проблемы в цвете полей, наложениях и т. Д. С некоторыми обширными шаблонами, такими как ListBox и комбинированное окно.
При связывании данных ваши данные не отображаются на экране, и вы не знаете, почему
Или проблема связана со сложными макетами.
Или проблема выравнивания или проблемы в цвете полей, наложениях и т. Д. С некоторыми обширными шаблонами, такими как ListBox и комбинированное окно.
Отладка XAML-программы — это то, что вы обычно делаете, чтобы проверить, работают ли ваши привязки; и если он не работает, то проверить, что не так. К сожалению, установка точек останова в привязках XAML невозможна, кроме как в Silverlight, но мы можем использовать окно «Вывод» для проверки ошибок привязки данных. Давайте посмотрим на следующий код XAML, чтобы найти ошибку в привязке данных.
<Window x:Class = "DataBindingOneWay.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <StackPanel Name = "Display"> <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0"> <TextBlock Text = "Name: " Margin = "10" Width = "100"/> <TextBlock Margin = "10" Width = "100" Text = "{Binding FirstName}"/> </StackPanel> <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0"> <TextBlock Text = "Title: " Margin = "10" Width = "100"/> <TextBlock Margin = "10" Width = "100" Text = "{Binding Title}" /> </StackPanel> </StackPanel> </Grid> </Window>
Текстовые свойства двух текстовых блоков статически устанавливаются в «Имя» и «Заголовок», тогда как в других двух текстовых блоках текстовые свойства привязываются к «Имя» и «Заголовок», но переменные класса — это «Имя» и «Название» в классе Employee, который показан ниже.
Мы намеренно написали неверное имя переменной, чтобы понять, где мы можем найти этот тип ошибки, когда желаемый результат не отображается.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DataBindingOneWay { public class Employee { public string Name { get; set; } public string Title { get; set; } public static Employee GetEmployee() { var emp = new Employee() { Name = "Ali Ahmed", Title = "Developer" }; return emp; } } }
Вот реализация класса MainWindow в коде C #.
using System; using System.Windows; using System.Windows.Controls; namespace DataBindingOneWay { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = Employee.GetEmployee(); } } }
Давайте запустим это приложение, и вы сразу увидите в нашем MainWindow, что мы успешно связались с заголовком этого объекта Employee, но имя не привязано.
Чтобы проверить, что случилось с именем, давайте посмотрим в окно вывода, где генерируется много логов.
Легко найти ошибку — просто найти ее, и вы найдете следующую ошибку, которая говорит: «Ошибка пути BindingExpression: свойство« FirstName »не найдено в объекте» Employe »
System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName' property not found on 'object' ''Employee' (HashCode=11611730)'. BindingExpression:Path = FirstName; DataItem = 'Employee' (HashCode = 11611730); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
Это ясно указывает на то, что FirstName не является членом класса Employee, поэтому это помогает устранить проблемы такого типа в вашем приложении.
Когда вы снова измените FirstName на Name, вы увидите желаемый результат.
Инструменты отладки пользовательского интерфейса для XAML
Инструменты отладки пользовательского интерфейса были представлены для XAML с Visual Studio 2015 для проверки кода XAML во время выполнения. С помощью этих инструментов код XAML представляется в виде визуального дерева вашего работающего приложения WPF, а также различных свойств элемента пользовательского интерфейса в дереве. Чтобы включить эти инструменты, выполните следующие действия.
- Перейдите в меню «Инструменты» и выберите «Параметры» в меню «Инструменты».
- Откроется следующее диалоговое окно.
- Перейдите в Общие параметры в разделе «Отладка» слева.
- Отметьте выделенную опцию, например «Включить инструменты отладки пользовательского интерфейса для XAML», и нажмите кнопку «ОК».
Теперь запустите любое приложение XAML или используйте следующий код XAML.
<Window x:Class = "XAMLTestBinding.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> <StackPanel> <ComboBox Name = "comboBox" Margin = "50" Width = "100"> <ComboBoxItem Content = "Green" /> <ComboBoxItem Content = "Yellow" IsSelected = "True" /> <ComboBoxItem Content = "Orange" /> </ComboBox> <TextBox Name = "textBox" Margin = "50" Width = "100" Height = "23" VerticalAlignment = "Top" Text = "{Binding ElementName = comboBox, Path = SelectedItem.Content, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}"> </TextBox> </StackPanel> </Window>
Когда вы запустите приложение, оно покажет Live Visual Tree, где все элементы показаны в дереве.
Это Live Visual Tree показывает полную структуру макета, чтобы понять, где расположены элементы пользовательского интерфейса. Но эта опция доступна только в Visual Studio 2015. Если вы используете более старую опцию Visual Studio, вы не можете использовать этот инструмент, однако есть другой инструмент, который может быть интегрирован с Visual Studio, такой как XAML Spy для Visual Studio , Вы можете скачать его с xamlspy
WPF — Пользовательские элементы управления
Приложения WPF позволяют создавать пользовательские элементы управления, что позволяет легко создавать многофункциональные и настраиваемые элементы управления. Пользовательские элементы управления используются, когда все встроенные элементы управления, предоставляемые Microsoft, не соответствуют вашим критериям или вы не хотите платить за сторонние элементы управления.
В этой главе вы узнаете, как создавать собственные элементы управления. Прежде чем мы начнем рассматривать пользовательские элементы управления, давайте сначала кратко рассмотрим пользовательский элемент управления.
Пользовательский контроль
Пользовательские элементы управления предоставляют возможность собирать и объединять различные встроенные элементы управления и упаковывать их в повторно используемый XAML. Пользовательские элементы управления используются в следующих сценариях —
-
Если элемент управления состоит из существующих элементов управления, т. Е. Вы можете создать один элемент управления из нескольких уже существующих элементов управления.
-
Если элемент управления не нуждается в поддержке тем. Пользовательские элементы управления не поддерживают сложные настройки, шаблоны элементов управления и сложные стили.
-
Если разработчик предпочитает писать элементы управления, используя модель с выделенным кодом, где представление, а затем прямой код для обработчиков событий.
-
Вы не будете делиться своим контролем между приложениями.
Если элемент управления состоит из существующих элементов управления, т. Е. Вы можете создать один элемент управления из нескольких уже существующих элементов управления.
Если элемент управления не нуждается в поддержке тем. Пользовательские элементы управления не поддерживают сложные настройки, шаблоны элементов управления и сложные стили.
Если разработчик предпочитает писать элементы управления, используя модель с выделенным кодом, где представление, а затем прямой код для обработчиков событий.
Вы не будете делиться своим контролем между приложениями.
пример
Давайте перейдем к примеру контроля пользователя и выполните шаги, приведенные ниже.
-
Создайте новый проект WPF, затем щелкните правой кнопкой мыши свое решение и выберите Добавить> Новый элемент …
Создайте новый проект WPF, затем щелкните правой кнопкой мыши свое решение и выберите Добавить> Новый элемент …
-
Откроется следующее окно. Теперь выберите User Control (WPF) и назовите его MyUserControl.
Откроется следующее окно. Теперь выберите User Control (WPF) и назовите его MyUserControl.
-
Нажмите кнопку Добавить, и вы увидите, что в ваше решение будут добавлены два новых файла (MyUserControl.xaml и MyUserControl.cs).
Нажмите кнопку Добавить, и вы увидите, что в ваше решение будут добавлены два новых файла (MyUserControl.xaml и MyUserControl.cs).
Вот код XAML, в котором кнопка и текстовое поле создаются с некоторыми свойствами в файле MyUserControl.xaml.
<UserControl x:Class = "WPFUserControl.MyUserControl" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300"> <Grid> <TextBox Height = "23" HorizontalAlignment = "Left" Margin = "80,49,0,0" Name = "txtBox" VerticalAlignment = "Top" Width = "200" /> <Button Content = "Click Me" Height = "23" HorizontalAlignment = "Left" Margin = "96,88,0,0" Name = "button" VerticalAlignment = "Top" Click = "button_Click" /> </Grid> </UserControl>
Ниже приведен код C # для события нажатия кнопки в файле MyUserControl.cs, который обновляет текстовое поле.
using System; using System.Windows; using System.Windows.Controls; namespace WPFUserControl { /// <summary> /// Interaction logic for MyUserControl.xaml /// </summary> public partial class MyUserControl : UserControl { public MyUserControl() { InitializeComponent(); } private void button_Click(object sender, RoutedEventArgs e) { txtBox.Text = "You have just clicked the button"; } } }
Вот реализация в MainWindow.xaml для добавления пользовательского элемента управления.
<Window x:Class = "XAMLUserControl.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:control = "clr-namespace:WPFUserControl" Title = "MainWindow" Height = "350" Width = "525"> <Grid> <control:MyUserControl/> </Grid> </Window>
Когда вы скомпилируете и выполните приведенный выше код, он выдаст следующее окно.
Нажав кнопку «Нажмите меня», вы заметите, что текст внутри текстового поля обновляется.
Пользовательские элементы управления
Пользовательский элемент управления — это класс, который предлагает собственный стиль и шаблон, которые обычно определяются в generic.xaml. Пользовательские элементы управления используются в следующих сценариях —
-
Если элемент управления не существует, и вы должны создать его с нуля.
-
Если вы хотите расширить или добавить функциональность к существующему элементу управления, добавив дополнительное свойство или дополнительную функциональность в соответствии с вашим конкретным сценарием.
-
Если ваши элементы управления должны поддерживать тематику и стиль.
-
Если вы хотите поделиться своим контролем между приложениями.
Если элемент управления не существует, и вы должны создать его с нуля.
Если вы хотите расширить или добавить функциональность к существующему элементу управления, добавив дополнительное свойство или дополнительную функциональность в соответствии с вашим конкретным сценарием.
Если ваши элементы управления должны поддерживать тематику и стиль.
Если вы хотите поделиться своим контролем между приложениями.
пример
Давайте рассмотрим пример, чтобы понять, как работают пользовательские элементы управления. Создайте новый проект WPF, затем щелкните правой кнопкой мыши свое решение и выберите Добавить> Новый элемент …
Откроется следующее окно. Теперь выберите Custom Control (WPF) и назовите его MyCustomControl .
Нажмите кнопку Добавить, и вы увидите, что в ваше решение будут добавлены два новых файла (Themes / Generic.xaml и MyCustomControl.cs).
Вот код XAML, стиль которого установлен для пользовательского элемента управления в файле Generic.xaml.
<ResourceDictionary xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "clr-namespace:WPFCustomControls"> <Style TargetType = "{x:Type local:MyCustomControl}" BasedOn = "{StaticResource {x:Type Button}}"> <Setter Property = "Background" Value = "LightSalmon" /> <Setter Property = "Foreground" Value = "Blue"/> </Style> </ResourceDictionary>
Вот код C # для класса MyCustomControl, который унаследован от класса кнопки и в конструкторе переопределяет метаданные.
using System; using System.Windows; using System.Windows.Controls; namespace WPFCustomControls { public class MyCustomControl : Button { static MyCustomControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl))); } } }
Вот реализация события щелчка настраиваемого элемента управления в C #, которая обновляет текст текстового блока.
using System; using System.Windows; using System.Windows.Controls; namespace WPFCustomControls { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void customControl_Click(object sender, RoutedEventArgs e) { txtBlock.Text = "You have just click your custom control"; } } }
Вот реализация в MainWindow.xaml для добавления пользовательского элемента управления и TextBlock.
<Window x:Class = "WPFCustomControls.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:control = "clr-namespace:WPFCustomControls" Title = "MainWindow" Height = "350" Width = "604"> <StackPanel> <control:MyCustomControl x:Name = "customControl" Content = "Click Me" Width = "70" Margin = "10" Click = "customControl_Click"/> <TextBlock Name = "txtBlock" Width = "250" Height = "30"/> </StackPanel> </Window>
Когда вы скомпилируете и выполните приведенный выше код, он создаст следующее окно с пользовательским элементом управления, который является настраиваемой кнопкой.
При нажатии на настроенную кнопку вы увидите, что текст внутри текстового блока обновляется.
WPF — обработка исключений
Исключением является любое состояние ошибки или непредвиденное поведение, возникающее во время выполнения программы. Исключения могут быть вызваны по многим причинам, некоторые из них следующие:
-
Ошибка в вашем коде или в коде, который вы вызываете (например, в общей библиотеке),
-
Недоступные ресурсы операционной системы,
-
Неожиданные условия, с которыми сталкивается общеязыковая среда выполнения (например, код, который невозможно проверить)
Ошибка в вашем коде или в коде, который вы вызываете (например, в общей библиотеке),
Недоступные ресурсы операционной системы,
Неожиданные условия, с которыми сталкивается общеязыковая среда выполнения (например, код, который невозможно проверить)
Синтаксис
Исключения имеют возможность переносить поток программы из одной части в другую. В .NET Framework обработка исключений имеет следующие четыре ключевых слова:
-
try — в этом блоке программа идентифицирует определенное условие, которое вызывает некоторое исключение.
-
catch — ключевое слово catch указывает на перехват исключения. За блоком try следует один или несколько блоков catch, чтобы перехватить исключение с помощью обработчика исключений в том месте программы, где вы хотите решить проблему.
-
finally — блок finally используется для выполнения заданного набора операторов независимо от того, было ли выброшено исключение или нет. Например, если вы открываете файл, он должен быть закрыт независимо от того, возбуждено ли исключение или нет.
-
throw — программа выдает исключение при обнаружении проблемы. Это делается с помощью ключевого слова throw.
try — в этом блоке программа идентифицирует определенное условие, которое вызывает некоторое исключение.
catch — ключевое слово catch указывает на перехват исключения. За блоком try следует один или несколько блоков catch, чтобы перехватить исключение с помощью обработчика исключений в том месте программы, где вы хотите решить проблему.
finally — блок finally используется для выполнения заданного набора операторов независимо от того, было ли выброшено исключение или нет. Например, если вы открываете файл, он должен быть закрыт независимо от того, возбуждено ли исключение или нет.
throw — программа выдает исключение при обнаружении проблемы. Это делается с помощью ключевого слова throw.
Синтаксис для использования этих четырех ключевых слов выглядит следующим образом:
try { ///This will still trigger the exception } catch (ExceptionClassName e) { // error handling code } catch (ExceptionClassName e) { // error handling code } catch (ExceptionClassName e) { // error handling code } finally { // statements to be executed }
Несколько операторов catch используются в тех случаях, когда блок try может вызвать более одного исключения в зависимости от ситуации потока программы.
иерархия
Почти все классы исключений в .NET Framework прямо или косвенно являются производными от класса Exception. Наиболее важные классы исключений, полученные из класса Exception, —
-
Класс ApplicationException — он поддерживает исключения, которые генерируются программами. Когда разработчик хочет определить исключение, класс должен быть производным от этого класса.
-
Класс SystemException — это базовый класс для всех предопределенных системных исключений времени выполнения. В следующей иерархии показаны стандартные исключения, предоставляемые средой выполнения.
Класс ApplicationException — он поддерживает исключения, которые генерируются программами. Когда разработчик хочет определить исключение, класс должен быть производным от этого класса.
Класс SystemException — это базовый класс для всех предопределенных системных исключений времени выполнения. В следующей иерархии показаны стандартные исключения, предоставляемые средой выполнения.
В следующей таблице перечислены стандартные исключения, предоставляемые средой выполнения, и условия, при которых вы должны создать производный класс.
Тип исключения | Базовый тип | Описание |
---|---|---|
исключение | объект | Базовый класс для всех исключений. |
SystemException | исключение | Базовый класс для всех ошибок во время выполнения. |
IndexOutOfRangeException | SystemException | Бросается средой выполнения только тогда, когда массив проиндексирован неправильно. |
NullReferenceException | SystemException | Брошенный средой выполнения только когда ссылка на нулевой объект. |
AccessViolationException | SystemException | Выбрасывается средой выполнения только при обращении к недействительной памяти. |
InvalidOperationException | SystemException | Брошенный методами, когда в недопустимом состоянии. |
ArgumentException | SystemException | Базовый класс для всех исключений аргументов. |
ArgumentNullException | ArgumentException | Вызывается методами, которые не позволяют аргументу быть нулевым. |
ArgumentOutOfRangeException | ArgumentException | Вызывается методами, которые проверяют, что аргументы находятся в заданном диапазоне. |
Внешнее исключение | SystemException | Базовый класс для исключений, которые возникают или нацелены на среды вне среды выполнения. |
SEHException | Внешнее исключение | Исключение, инкапсулирующее Win32 структурированную информацию обработки исключений. |
пример
Давайте рассмотрим простой пример, чтобы лучше понять концепцию. Начните с создания нового проекта WPF с именем WPFExceptionHandling .
Перетащите одно текстовое поле с панели инструментов в окно дизайна. Следующий код XAML создает текстовое поле и инициализирует его с некоторыми свойствами.
<Window x:Class = "WPFExceptionHandling.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:WPFExceptionHandling" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <TextBox x:Name = "textBox" HorizontalAlignment = "Left" Height = "241" Margin = "70,39,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "453"/> </Grid> </Window>
Вот чтение файла с обработкой исключений в C #.
using System; using System.IO; using System.Windows; namespace WPFExceptionHandling { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); ReadFile(0); } void ReadFile(int index) { string path = @"D:\Test.txt"; StreamReader file = new StreamReader(path); char[] buffer = new char[80]; try { file.ReadBlock(buffer, index, buffer.Length); string str = new string(buffer); str.Trim(); textBox.Text = str; } catch (Exception e) { MessageBox.Show("Error reading from "+ path + "\nMessage = "+ e.Message); } finally { if (file != null) { file.Close(); } } } } }
Когда вы скомпилируете и выполните приведенный выше код, он создаст следующее окно, в котором текст отображается внутри текстового поля.
Когда возникает исключение или вы его выбрасываете вручную (как в следующем коде), тогда появится сообщение с ошибкой.
using System; using System.IO; using System.Windows; namespace WPFExceptionHandling { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); ReadFile(0); } void ReadFile(int index) { string path = @"D:\Test.txt"; StreamReader file = new StreamReader(path); char[] buffer = new char[80]; try { file.ReadBlock(buffer, index, buffer.Length); string str = new string(buffer); throw new Exception(); str.Trim(); textBox.Text = str; } catch (Exception e) { MessageBox.Show("Error reading from "+ path + "\nMessage = "+ e.Message); } finally { if (file != null) { file.Close(); } } } } }
Если во время выполнения вышеуказанного кода возникнет исключение, будет отображено следующее сообщение.
Мы рекомендуем вам выполнить приведенный выше код и поэкспериментировать с его функциями.
WPF — Локализация
Локализация — это перевод ресурсов приложения в локализованные версии для определенных культур, которые поддерживает приложение.
Когда вы разрабатываете свое приложение и ваше приложение доступно только на одном языке, вы ограничиваете количество своих клиентов и размер вашего бизнеса. Если вы хотите увеличить свою клиентскую базу, что также увеличит ваш бизнес, то ваш продукт должен быть доступен и доступен для глобальной аудитории. Экономичная локализация вашего продукта — один из лучших и наиболее экономичных способов охвата большего количества клиентов.
В WPF локализуемые приложения очень легко создавать с помощью файла resx, который является самым простым решением для локализации. Давайте рассмотрим простой пример, чтобы понять, как это работает —
-
Создайте новый проект WPF с именем WPFLocalization .
-
В обозревателе решений вы увидите файл Resources.resx в папке «Свойства».
Создайте новый проект WPF с именем WPFLocalization .
В обозревателе решений вы увидите файл Resources.resx в папке «Свойства».
-
Измените модификатор доступа с внутреннего на публичный, чтобы он был доступен в файле XAML.
Измените модификатор доступа с внутреннего на публичный, чтобы он был доступен в файле XAML.
-
Теперь добавьте имя и значения следующей строки, которые мы будем использовать в нашем приложении.
Теперь добавьте имя и значения следующей строки, которые мы будем использовать в нашем приложении.
-
Сделайте две копии файла Resources.resx с именами Resources.en.resx и Resources.ru-RU.resx. Это соглашения об именах, относящиеся к языку и названию страны / региона, и их можно найти на странице Справочника API поддержки национальных языков ( https://msdn.microsoft.com/en-us/goglobal/bb896001.aspx ).
-
Измените значения в Resources.ru-RU.resx на русские слова, как показано ниже.
Сделайте две копии файла Resources.resx с именами Resources.en.resx и Resources.ru-RU.resx. Это соглашения об именах, относящиеся к языку и названию страны / региона, и их можно найти на странице Справочника API поддержки национальных языков ( https://msdn.microsoft.com/en-us/goglobal/bb896001.aspx ).
Измените значения в Resources.ru-RU.resx на русские слова, как показано ниже.
-
Давайте перейдем в окно дизайна и перетащим три текстовых поля, три надписи и три кнопки.
-
В файле XAML сначала добавьте объявление пространства имен, чтобы использовать ресурсы локализации xmlns: p = «clr-namespace: WPFLocalization.Properties»
-
Установите свойства всех элементов управления, как показано ниже. В этом примере мы не будем использовать жестко закодированные строки для содержимого меток, кнопок и заголовка окна в файле XAML. Мы будем использовать строки, которые определены в файлах * .resx. Например, для Заголовка окна мы используем строку Заголовка, которая определена в файле * .resx, например, «Title =» {x: Static p: Resources.Title} «»
-
Вот файл XAML, в котором элементы управления создаются и инициализируются с различными свойствами.
Давайте перейдем в окно дизайна и перетащим три текстовых поля, три надписи и три кнопки.
В файле XAML сначала добавьте объявление пространства имен, чтобы использовать ресурсы локализации xmlns: p = «clr-namespace: WPFLocalization.Properties»
Установите свойства всех элементов управления, как показано ниже. В этом примере мы не будем использовать жестко закодированные строки для содержимого меток, кнопок и заголовка окна в файле XAML. Мы будем использовать строки, которые определены в файлах * .resx. Например, для Заголовка окна мы используем строку Заголовка, которая определена в файле * .resx, например, «Title =» {x: Static p: Resources.Title} «»
Вот файл XAML, в котором элементы управления создаются и инициализируются с различными свойствами.
<Window x:Class = "WPFLocalization.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "clr-namespace:WPFLocalization" xmlns:p = "clr-namespace:WPFLocalization.Properties" Title = "{x:Static p:Resources.Title}" Height = "350" Width = "604"> <Grid> <TextBox x:Name = "textBox" HorizontalAlignment = "Left" Height = "23" Margin = "128,45,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "304"/> <Label x:Name = "label" Content = "{x:Static p:Resources.Name}" HorizontalAlignment = "Left" Margin = "52,45,0,0" VerticalAlignment = "Top" Width = "86"/> <TextBox x:Name = "textBox1" HorizontalAlignment = "Left" Height = "23" Margin = "128,102,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "304"/> <Label x:Name = "label1" Content = "{x:Static p:Resources.Address}" HorizontalAlignment = "Left" Margin = "52,102,0,0" VerticalAlignment = "Top" Width = "86"/> <TextBox x:Name = "textBox2" HorizontalAlignment = "Left" Height = "23" Margin = "128,157,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "80"/> <Label x:Name = "label2" Content = "{x:Static p:Resources.Age}" HorizontalAlignment = "Left" Margin = "52,157,0,0" VerticalAlignment = "Top" Width = "86"/> <Button x:Name = "button" Content = "{x:Static p:Resources.OK_Button}" HorizontalAlignment = "Left" Margin = "163,241,0,0" VerticalAlignment = "Top" Width = "75"/> <Button x:Name = "button1" Content = "{x:Static p:Resources.Cancel_Button}" HorizontalAlignment = "Left" Margin = "282,241,0,0" VerticalAlignment = "Top" Width = "75"/> <Button x:Name = "button2" Content = "{x:Static p:Resources.Help_Button}" HorizontalAlignment = "Left" Margin = "392,241,0,0" VerticalAlignment = "Top" Width = "75"/> </Grid> </Window>
-
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно, которое содержит различные элементы управления.
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно, которое содержит различные элементы управления.
-
По умолчанию программа использует по умолчанию Resources.resx. Если вы хотите отобразить текст на русском языке, который определен в файле Resources.ru-RU.resx, вам нужно будет явно указать язык при запуске программы в файле App.xaml, как показано ниже.
По умолчанию программа использует по умолчанию Resources.resx. Если вы хотите отобразить текст на русском языке, который определен в файле Resources.ru-RU.resx, вам нужно будет явно указать язык при запуске программы в файле App.xaml, как показано ниже.
using System.Windows; namespace WPFLocalization { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : Application { App() { System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("ru-RU"); //System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en"); } } }
Когда вы запустите свое приложение, вы увидите весь текст на русском языке.
Мы рекомендуем вам выполнить приведенный выше код и создать файлы resx для других культур.
WPF — Взаимодействие
В WPF взаимодействие показывает, как представление взаимодействует с элементами управления, расположенными в этом представлении. Наиболее известные взаимодействия имеют два типа —
- поведения
- Перетащить
поведения
Поведение было введено с Expression Blend 3, которая может заключать в себе некоторые функциональные возможности в повторно используемом компоненте. Чтобы добавить дополнительные варианты поведения, вы можете прикрепить эти компоненты к элементам управления. Поведения обеспечивают большую гибкость для простого проектирования сложных взаимодействий с пользователем.
Давайте рассмотрим простой пример, в котором поведение ControlStoryBoardAction прикреплено к элементам управления.
-
Создайте новый проект WPF с именем WPFBehavior.
-
Следующий код XAML создает эллипс и две кнопки для управления движением эллипса.
Создайте новый проект WPF с именем WPFBehavior.
Следующий код XAML создает эллипс и две кнопки для управления движением эллипса.
<Window 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:WPFBehaviors" xmlns:i = "http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei = "http://schemas.microsoft.com/expression/2010/interactions" x:Class = "WPFBehaviors.MainWindow" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> <Window.Resources> <Storyboard x:Key = "Storyboard1" RepeatBehavior = "Forever" AutoReverse = "True"> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "(UIElement.RenderTransform).(TransformGroup.Children )[3].(TranslateTransform.X)" Storyboard.TargetName = "ellipse"> <EasingDoubleKeyFrame KeyTime = "0:0:1" Value = "301.524"/> <EasingDoubleKeyFrame KeyTime = "0:0:2" Value = "2.909"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "(UIElement.RenderTransform).(TransformGroup.Children )[3].(TranslateTransform.Y)" Storyboard.TargetName = "ellipse"> <EasingDoubleKeyFrame KeyTime = "0:0:1" Value = "-0.485"/> <EasingDoubleKeyFrame KeyTime = "0:0:2" Value = "0"/> </DoubleAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty = "(ContentControl.Content)" Storyboard.TargetName = "button"> <DiscreteObjectKeyFrame KeyTime = "0" Value = "Play"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty = "(ContentControl.Content)" Storyboard.TargetName = "button1"> <DiscreteObjectKeyFrame KeyTime = "0" Value = "Stop"/> <DiscreteObjectKeyFrame KeyTime = "0:0:2" Value = "Stop"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </Window.Resources> <Window.Triggers> <EventTrigger RoutedEvent = "FrameworkElement.Loaded"> <BeginStoryboard Storyboard = "{StaticResource Storyboard1}"/> </EventTrigger> </Window.Triggers> <Grid> <Ellipse x:Name = "ellipse" Fill = "#FFAAAAC5" HorizontalAlignment = "Left" Height = "50.901" Margin = "49.324,70.922,0,0" Stroke = "Black" VerticalAlignment = "Top" Width = "73.684" RenderTransformOrigin = "0.5,0.5"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Button x:Name = "button" Content = "Play" HorizontalAlignment = "Left" Height = "24.238" Margin = "63.867,0,0,92.953" VerticalAlignment = "Bottom" Width = "74.654"> <i:Interaction.Triggers> <i:EventTrigger EventName = "Click"> <ei:ControlStoryboardAction Storyboard = "{StaticResource Storyboard1}"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button x:Name = "button1" Content = "Stop" HorizontalAlignment = "Left" Height = "24.239" Margin = "160.82,0,0,93.922" VerticalAlignment = "Bottom" Width = "75.138"> <i:Interaction.Triggers> <i:EventTrigger EventName = "Click"> <ei:ControlStoryboardAction ControlStoryboardOption = "Stop" Storyboard = "{StaticResource Storyboard1}"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> </Grid> </Window>
Когда вы скомпилируете и выполните приведенный выше код, он создаст следующее окно, которое содержит эллипс и две кнопки.
Когда вы нажмете кнопку воспроизведения, она начнет двигаться слева направо, а затем вернется в исходное положение. Кнопка Стоп остановит движение эллипса.
Перетащить
Перетаскивание по пользовательскому интерфейсу может значительно повысить эффективность и производительность приложения. Существует очень мало приложений, в которых используются функции перетаскивания, потому что люди думают, что это сложно реализовать. В некоторой степени трудно обрабатывать функцию перетаскивания, но в WPF вы можете справиться с ней довольно легко.
Давайте рассмотрим простой пример, чтобы понять, как это работает. Мы создадим приложение, в котором вы можете перетаскивать цвета из одного прямоугольника в другой.
-
Создайте новый проект WPF с именем WPFDragAndDrop.
-
Перетащите пять прямоугольников в окно конструктора и установите свойства, как показано в следующем XAML-файле.
Создайте новый проект WPF с именем WPFDragAndDrop.
Перетащите пять прямоугольников в окно конструктора и установите свойства, как показано в следующем XAML-файле.
<Window x:Class = "WPFDragAndDrop.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:WPFDragAndDrop" mc:Ignorable = "d" Title = "MainWindow" Height = "402.551" Width = "604"> <Grid> <Rectangle Name = "Target" Fill = "AliceBlue" HorizontalAlignment = "Left" Height = "345" Margin = "10,10,0,0" Stroke = "Black" VerticalAlignment = "Top" Width = "387" AllowDrop = "True" Drop = "Target_Drop"/> <Rectangle Fill = "Beige" HorizontalAlignment = "Left" Height = "65" Margin = "402,10,0,0" Stroke = "Black" VerticalAlignment = "Top" Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> <Rectangle Fill = "LightBlue" HorizontalAlignment = "Left" Height = "65" Margin = "402,80,0,0" Stroke = "Black" VerticalAlignment = "Top" Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> <Rectangle Fill = "LightCoral" HorizontalAlignment = "Left" Height = "65" Margin = "402,150,0,0" Stroke = "Black" VerticalAlignment = "Top" Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> <Rectangle Fill = "LightGray" HorizontalAlignment = "Left" Height = "65" Margin = "402,220,0,0" Stroke = "Black" VerticalAlignment = "Top" Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> <Rectangle Fill = "OliveDrab" HorizontalAlignment = "Left" Height = "65" Margin = "402,290,0,-7" Stroke = "Black" VerticalAlignment = "Top" Width = "184" MouseLeftButtonDown = "Rect_MLButtonDown"/> </Grid> </Window>
-
Первый прямоугольник является целевым прямоугольником, поэтому пользователь может перетащить цвет из другого прямоугольника в целевой прямоугольник.
-
Ниже приведены реализации событий в C # для перетаскивания.
Первый прямоугольник является целевым прямоугольником, поэтому пользователь может перетащить цвет из другого прямоугольника в целевой прямоугольник.
Ниже приведены реализации событий в C # для перетаскивания.
using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; namespace WPFDragAndDrop { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Rect_MLButtonDown(object sender, MouseButtonEventArgs e) { Rectangle rc = sender as Rectangle; DataObject data = new DataObject(rc.Fill); DragDrop.DoDragDrop(rc, data,DragDropEffects.Move); } private void Target_Drop(object sender, DragEventArgs e) { SolidColorBrush scb = (SolidColorBrush)e.Data.GetData(typeof(SolidColorBrush)); Target.Fill = scb; } } }
Когда вы запустите ваше приложение, оно выдаст следующее окно.
Если вы перетащите цвет из прямоугольника с правой стороны и поместите его в большой прямоугольник слева, вы сразу увидите его эффект.
Давайте перетащим 4- й с правой стороны.
Вы можете видеть, что цвет целевого прямоугольника изменился. Мы рекомендуем вам выполнить приведенный выше код и поэкспериментировать с его функциями.
WPF — 2D графика
WPF предоставляет широкий спектр 2D-графики, которые могут быть улучшены в соответствии с требованиями вашего приложения. WPF поддерживает объекты Drawing и Shape, которые используются для рисования графического содержимого.
Формы и рисунок
-
Класс Shape является производным от класса FrameworkElement. Объекты Shape можно использовать внутри панелей и большинства элементов управления.
-
WPF предоставляет некоторые базовые объекты формы, которые являются производными от класса Shape, такие как Ellipse, Line, Path, Polygon, Polyline и Rectangle.
-
Рисующие объекты, с другой стороны, не являются производными от класса FrameworkElement и обеспечивают более легкую реализацию.
-
Рисование объектов проще по сравнению с объектами Shape. Они также имеют лучшие эксплуатационные характеристики.
Класс Shape является производным от класса FrameworkElement. Объекты Shape можно использовать внутри панелей и большинства элементов управления.
WPF предоставляет некоторые базовые объекты формы, которые являются производными от класса Shape, такие как Ellipse, Line, Path, Polygon, Polyline и Rectangle.
Рисующие объекты, с другой стороны, не являются производными от класса FrameworkElement и обеспечивают более легкую реализацию.
Рисование объектов проще по сравнению с объектами Shape. Они также имеют лучшие эксплуатационные характеристики.
пример
Давайте рассмотрим простой пример, чтобы понять, как использовать различные формы объекта.
-
Создайте новый проект WPF с именем WPF2DGraphics .
-
Следующий код создает различные типы фигур.
Создайте новый проект WPF с именем WPF2DGraphics .
Следующий код создает различные типы фигур.
<Window x:Class = "WPF2DGraphics.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:WPF2DGraphics" xmlns:PresentationOptions = "http://schemas.microsoft.com/winfx/2006/xaml/present ation/options" mc:Ignorable = "PresentationOptions" Title = "MainWindow" Height = "400" Width = "604"> <StackPanel> <Ellipse Width = "100" Height = "60" Name = "sample" Margin = "10"> <Ellipse.Fill> <RadialGradientBrush> <GradientStop Offset = "0" Color = "AliceBlue"/> <GradientStop Offset = "1" Color = "Gray"/> <GradientStop Offset = "2" Color = "Red"/> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> <Path Stroke = "Red" StrokeThickness = "5" Data = "M 10,70 L 200,70" Height = "42.085" Stretch = "Fill" Margin = "140.598,0,146.581,0" /> <Path Stroke = "BlueViolet" StrokeThickness = "5" Data = "M 20,100 A 100,56 42 1 0 200,10" Height = "81.316" Stretch = "Fill" Margin = "236.325,0,211.396,0" /> <Path Fill = "LightCoral" Margin = "201.424,0,236.325,0" Stretch = "Fill" Height = "124.929"> <Path.Data> <PathGeometry> <PathFigure StartPoint = "50,0" IsClosed = "True"> <LineSegment Point = "100,50"/> <LineSegment Point = "50,100"/> <LineSegment Point = "0,50"/> </PathFigure> </PathGeometry> </Path.Data> </Path> </StackPanel> </Window>
Когда вы скомпилируете и выполните приведенный выше код, он создаст эллипс, прямую линию, дугу и многоугольник.
пример
Давайте посмотрим на другой пример, который показывает, как рисовать область с рисунком.
-
Создайте новый проект WPF с именем WPF2DGraphics1 .
-
Следующий код XAML показывает, как рисовать по-разному при рисовании изображения.
Создайте новый проект WPF с именем WPF2DGraphics1 .
Следующий код XAML показывает, как рисовать по-разному при рисовании изображения.
<Window x:Class = "WPF2DGraphics1.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:PresentationOptions = "http://schemas.microsoft.com/winfx/2006/xaml/present ation/options" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "PresentationOptions" xmlns:local = "clr-namespace:WPF2DGraphics1" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <Border BorderBrush = "Gray" BorderThickness = "1" HorizontalAlignment = "Left" VerticalAlignment = "Top" Margin = "20"> <Image Stretch = "None"> <Image.Source> <DrawingImage PresentationOptions:Freeze = "True"> <DrawingImage.Drawing> <DrawingGroup> <ImageDrawing Rect = "300,100,300,180" ImageSource = "Images\DSC_0104.JPG"/> <ImageDrawing Rect = "0,100,250,100" ImageSource = "Images\DSC_0104.JPG"/> <ImageDrawing Rect = "150,0,25,25" ImageSource = "Images\DSC_0104.JPG"/> <ImageDrawing Rect = "0,0,75,75" ImageSource = "Images\DSC_0104.JPG"/> </DrawingGroup> </DrawingImage.Drawing> </DrawingImage> </Image.Source> </Image> </Border> </Grid> </Window>
Когда вы запустите ваше приложение, оно выдаст следующий вывод:
Мы рекомендуем вам выполнить приведенный выше код и попробовать больше 2D-форм и рисунков.
WPF — 3D Графика
Windows Presentation Foundation (WPF) предоставляет функции для рисования, преобразования и анимации трехмерной графики в соответствии с требованиями вашего приложения. Он не поддерживает полноценную разработку 3D-игр, но на некотором уровне вы можете создавать 3D-графику.
Комбинируя 2D и 3D графику, вы также можете создавать богатые элементы управления, предоставлять сложные иллюстрации данных или улучшать пользовательский интерфейс приложения. Элемент Viewport3D содержит 3D-модель в нашем приложении WPF.
пример
Давайте рассмотрим простой пример, чтобы понять, как использовать 3D-графику.
-
Создайте новый проект WPF с именем WPF3DGraphics .
-
Следующий код XAML показывает, как создать 2D-объект, используя трехмерную геометрию.
Создайте новый проект WPF с именем WPF3DGraphics .
Следующий код XAML показывает, как создать 2D-объект, используя трехмерную геометрию.
<Window x:Class = "WPF3DGraphics.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local = "clr-namespace:WPF3DGraphics" mc:Ignorable = "d" Title = "MainWindow" Height = "500" Width = "604"> <Grid> <Viewport3D> <Viewport3D.Camera> <PerspectiveCamera Position = "2,0,10" LookDirection = "0.2,0.4,-1" FieldOfView = "65" UpDirection = "0,1,0" /> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Content> <Model3DGroup> <AmbientLight Color = "Bisque" /> <GeometryModel3D> <GeometryModel3D.Geometry> <MeshGeometry3D Positions = "0,0,0 0,8,0 10,0,0 8,8,0" Normals = "0,0,1 0,0,1 0,0,1 0,0,1" TriangleIndices = "0,2,1 1,2,3"/> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <DiffuseMaterial Brush = "Bisque" /> </GeometryModel3D.Material> </GeometryModel3D> </Model3DGroup> </ModelVisual3D.Content> </ModelVisual3D> </Viewport3D> </Grid> </Window>
Когда вы скомпилируете и выполните приведенный выше код, он создаст 2D-объект в 3D.
пример
Давайте посмотрим на другой пример, который показывает 3D-объект.
-
Создайте новый проект WPF с именем WPF3DGraphics1
-
Следующий код XAML создает 3D-объект и ползунок. С помощью ползунка вы можете вращать этот 3D-объект.
Создайте новый проект WPF с именем WPF3DGraphics1
Следующий код XAML создает 3D-объект и ползунок. С помощью ползунка вы можете вращать этот 3D-объект.
<Window x:Class = "WPF3DGraphics1.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:WPF3DGraphics1" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> <Grid> <Viewport3D Name="viewport3D1"> <Viewport3D.Camera> <PerspectiveCamera x:Name = "camMain" Position = "6 5 4" LookDirection = "-6 -5 -4"> </PerspectiveCamera> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight x:Name = "dirLightMain" Direction = "-1,-1,-1"> </DirectionalLight> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D x:Name = "MyModel"> <ModelVisual3D.Content> <GeometryModel3D> <GeometryModel3D.Geometry> <MeshGeometry3D x:Name = "meshMain" Positions = "0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 1 0 1 0 1 1 0 1 1" TriangleIndices = "2 3 1 3 1 0 7 1 3 7 5 1 6 5 7 6 4 5 6 2 0 2 0 4 2 7 3 2 6 7 0 1 5 0 5 4"> </MeshGeometry3D> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <DiffuseMaterial x:Name = "matDiffuseMain"> <DiffuseMaterial.Brush> <SolidColorBrush Color = "Bisque"/> </DiffuseMaterial.Brush> </DiffuseMaterial> </GeometryModel3D.Material> </GeometryModel3D> </ModelVisual3D.Content> <ModelVisual3D.Transform> <RotateTransform3D> <RotateTransform3D.Rotation> <AxisAngleRotation3D x:Name = "rotate" Axis = "1 2 1"/> </RotateTransform3D.Rotation> </RotateTransform3D> </ModelVisual3D.Transform> </ModelVisual3D> </Viewport3D> <Slider Height = "23" HorizontalAlignment = "Left" Margin = "145,271,0,0" Name = "slider1" VerticalAlignment = "Top" Width = "269" Maximum = "360" Value = "{Binding ElementName = rotate, Path=Angle}" /> </Grid> </Window>
Когда вы запустите ваше приложение, оно создаст 3D-объект и слайдер в вашем окне.
Когда вы двигаете ползунок, объект в вашем окне также будет вращаться.
Мы рекомендуем вам выполнить приведенный выше код и попробовать больше 3D-геометрии.
WPF — Мультимедиа
Приложения WPF поддерживают видео и аудио с помощью MediaElement . Это позволяет интегрировать аудио и видео в приложение. Класс MediaElement работает аналогично классу Image. Вы просто указываете это на средства массовой информации, и это оказывает. Основное отличие состоит в том, что это будет движущееся изображение, но если вы укажете его на файл, который содержит только аудио и не содержит видео, например, MP3, он будет воспроизводиться, не показывая ничего на экране.
WPF поддерживает все типы видео / аудио форматов в зависимости от конфигурации машины. Если медиа-файл воспроизводит Media Player, он также будет работать в WPF на том же компьютере.
пример
Давайте рассмотрим пример, чтобы понять, как интегрировать мультимедиа в ваше приложение.
-
Создайте новый проект WPF с именем WPFMultimedia .
-
Следующий код XAML создает медиа-элемент и три кнопки и инициализирует их с некоторыми свойствами.
Создайте новый проект WPF с именем WPFMultimedia .
Следующий код XAML создает медиа-элемент и три кнопки и инициализирует их с некоторыми свойствами.
<Window x:Class = "WPFMultimedia.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:WPFMultimedia" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <StackPanel HorizontalAlignment = "Center" VerticalAlignment = "Center"> <MediaElement Name = "myMedia" Source = "D:\MicrosoftMVA.mp4" LoadedBehavior = "Manual" Width = "591" Height = "274" /> <StackPanel Orientation = "Horizontal" Margin = "0,10,0,0"> <Button Content = "Play" Margin = "0,0,10,0" Padding = "5" Click = "mediaPlay" /> <Button Content = "Pause" Margin = "0,0,10,0" Padding = "5" Click = "mediaPause" /> <Button x:Name = "muteButt" Content = "Mute" Padding = "5" Click = "mediaMute" /> </StackPanel> </StackPanel> </Grid> </Window>
Вот реализация событий Click в C # для разных кнопок.
using System; using System.Windows; namespace WPFMultimedia { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); myMedia.Volume = 100; myMedia.Play(); } void mediaPlay(Object sender, EventArgs e) { myMedia.Play(); } void mediaPause(Object sender, EventArgs e) { myMedia.Pause(); } void mediaMute(Object sender, EventArgs e) { if (myMedia.Volume == 100) { myMedia.Volume = 0; muteButt.Content = "Listen"; } else { myMedia.Volume = 100; muteButt.Content = "Mute"; } } } }
Когда вы скомпилируете и выполните приведенный выше код, он выдаст следующее окно. Вы можете воспроизводить видео и управлять его воспроизведением с помощью трех кнопок.
С помощью кнопок вы можете приостанавливать, отключать звук и воспроизводить видео.
Синтезатор речи
WPF имеет функции для преобразования текста в речь. Этот API включен в пространство имен System.Speech. Класс SpeechSynthesizer преобразует текст в произнесенные слова.
пример
Давайте посмотрим на простой пример.
-
Создайте новый проект WPF с именем WPFTextToSpeech .
-
Нам понадобится сборка System.Speech для добавления в качестве ссылки на класс SpeechSynthesizer для работы.
-
Щелкните правой кнопкой мыши на References и выберите Add Reference.
Создайте новый проект WPF с именем WPFTextToSpeech .
Нам понадобится сборка System.Speech для добавления в качестве ссылки на класс SpeechSynthesizer для работы.
Щелкните правой кнопкой мыши на References и выберите Add Reference.
-
Откроется диалоговое окно Reference Manager. Теперь установите флажок System.Speech
Откроется диалоговое окно Reference Manager. Теперь установите флажок System.Speech
-
Нажмите кнопку ОК. Вы можете увидеть сборку System.Speech в ваших ссылках.
Нажмите кнопку ОК. Вы можете увидеть сборку System.Speech в ваших ссылках.
-
Теперь перетащите кнопку и текстовое поле в окно дизайна из панели инструментов.
-
Следующий код XAML создает кнопку и текстовое поле и инициализирует их с некоторыми свойствами.
Теперь перетащите кнопку и текстовое поле в окно дизайна из панели инструментов.
Следующий код XAML создает кнопку и текстовое поле и инициализирует их с некоторыми свойствами.
<Window x:Class = "WPFTextToSpeech.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:WPFTextToSpeech" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <Button x:Name = "button" Content = "Speak" HorizontalAlignment = "Left" Margin = "218,176,0,0" VerticalAlignment = "Top" Width = "75"/> <TextBox x:Name = "textBox" HorizontalAlignment = "Left" Height = "23" Margin = "60,104,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "418"/> </Grid> </Window>
-
Вот простая реализация в C #, которая преобразует текст внутри текстового поля в произнесенные слова.
Вот простая реализация в C #, которая преобразует текст внутри текстового поля в произнесенные слова.
using System.Speech.Synthesis; using System.Windows; namespace WPFTextToSpeech { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void button_Click(object sender, RoutedEventArgs e) { if (textBox.Text != "") { SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(); speechSynthesizer.Speak(textBox.Text); } else { MessageBox.Show("Write some thing in the textbox!"); } } } }
Когда вы скомпилируете и выполните приведенный выше код, он выдаст следующее окно. Теперь введите Hello World внутри текстового поля и нажмите кнопку «Говорить».
Будет издан звук «Hello World». Если вы ничего не введете в текстовое поле, то появится следующее сообщение.
Мы рекомендуем вам выполнить приведенные выше примеры.