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.
- Он содержит смесь управляемого и неуправляемого кода.
Основные компоненты архитектуры WPF показаны на рисунке ниже. Самая важная часть кода WPF -
- Структура представления
- Ядро презентации
- Milcore
В presentation framework и presentation core были написаны в управляемом коде. Milcore является частью неуправляемого кода, который обеспечивает тесную интеграцию с DirectX (отвечает за отображение и рендеринг). CLR делает процесс разработки более продуктивным, предлагая множество функций, таких как управление памятью, обработка ошибок и т. д.
WPF - Преимущества
В более ранних структурах графического интерфейса пользователя не было реального разделения между тем, как приложение выглядит и как оно ведет себя. И графический интерфейс, и поведение были созданы на одном языке, например C # или VB.Net, что потребовало бы дополнительных усилий от разработчика для реализации как пользовательского интерфейса, так и поведения, связанного с ним.
В WPF элементы пользовательского интерфейса разрабатываются на XAML, тогда как поведение может быть реализовано на процедурных языках, таких как C # и VB.Net. Так что очень легко отделить поведение от кода дизайнера.
С XAML программисты могут работать параллельно с дизайнерами. Разделение между графическим интерфейсом пользователя и его поведением может позволить нам легко изменить внешний вид элемента управления с помощью стилей и шаблонов.
WPF - Возможности
WPF - это мощный фреймворк для создания приложений Windows. Он поддерживает множество замечательных функций, некоторые из которых перечислены ниже -
Характерная черта | Описание |
---|---|
Контроль внутри Control | Позволяет определить элемент управления внутри другого элемента управления как контент. |
Связывание данных | Механизм для отображения и взаимодействия с данными между элементами пользовательского интерфейса и объектом данных в пользовательском интерфейсе. |
Медиа услуги | Предоставляет интегрированную систему для создания пользовательских интерфейсов с общими мультимедийными элементами, такими как изображения, аудио и видео. |
Шаблоны | В WPF вы можете определить внешний вид элемента напрямую с помощью шаблона |
Анимации | Создание интерактивности и движения в пользовательском интерфейсе |
Альтернативный ввод | Поддерживает мультисенсорный ввод в Windows 7 и выше. |
Direct3D | Позволяет отображать более сложную графику и настраиваемые темы |
Microsoft предоставляет два важных инструмента для разработки приложений WPF.
- Visual Studio
- Смесь выражений
Оба инструмента могут создавать проекты WPF, но дело в том, что Visual Studio больше используется разработчиками, а Blend - чаще дизайнерами. В этом руководстве мы в основном будем использовать Visual Studio.
Установка
Microsoft предоставляет бесплатную версию Visual Studio, которую можно загрузить с VisualStudio .
Загрузите файлы и следуйте инструкциям ниже, чтобы настроить среду разработки приложений WPF в вашей системе.
После завершения загрузки запустите installer. Появится следующий диалог.
Щелкните значок Install кнопку, и начнется процесс установки.
После успешного завершения процесса установки вы увидите следующее диалоговое окно.
Закройте это диалоговое окно и при необходимости перезагрузите компьютер.
Теперь откройте Visual Studio из меню «Пуск», в котором откроется следующее диалоговое окно.
- Когда все будет сделано, вы увидите главное окно Visual Studio.
Теперь вы готовы создать свое первое приложение WPF.
В этой главе мы разработаем простое приложение Hello World WPF. Итак, давайте начнем с простой реализации, выполнив шаги, указанные ниже.
- Щелкните File> New> Project меню.
- Откроется следующее диалоговое окно.
В разделе «Шаблоны» выберите Visual C # и на средней панели выберите «Приложение WPF».
Дайте проекту имя. ТипHelloWorld в поле имени и нажмите кнопку ОК.
По умолчанию создаются два файла, один из которых XAML файл (mainwindow.xaml), а второй - CS файл (mainwindow.cs)
В mainwindow.xaml вы увидите два подокна, одно из которых design window а другой - source (XAML) window.
В приложении 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.
<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. XAML расшифровывается как Extensible Application Markup Language. Это простой и декларативный язык, основанный на XML.
В 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 содержит различные виды информации. В следующей таблице кратко объясняется роль каждой информации.
Информация | Описание |
---|---|
<Окно | Это открывающий объектный элемент или контейнер корня. |
x: Class = "Resources.MainWindow" | Это объявление частичного класса, которое связывает разметку с определенным за ним кодом частичного класса. |
xmlns = "http://schemas.microsoft.com/win fx / 2006 / xaml / презентация" | Сопоставляет пространство имен XAML по умолчанию для клиента / платформы WPF |
xmlns: x = "http://schemas.microsoft.com/w infx / 2006 / xaml" | Пространство имен XAML для языка XAML, которое сопоставляет его с префиксом x: |
> | Конец объекта элемент корня |
<Сетка> </Grid> |
Это начальный и закрывающий теги пустого объекта сетки. |
</Window> | Закрытие элемента объекта |
Правила синтаксиса для XAML почти аналогичны XML. Если вы посмотрите на документ XAML, то заметите, что на самом деле это действительный файл XML, но файл XML не обязательно является файлом XAML. Это связано с тем, что в XML значение атрибутов должно быть строкой, а в XAML это может быть другой объект, известный как синтаксис элемента свойства.
Синтаксис элемента 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 содержит текстовый блок в качестве дочернего элемента
<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 стремится сделать возможным управление всеми визуальными аспектами пользовательского интерфейса с помощью разметки.
Существует множество технологий, в которых элементы и компоненты упорядочены в древовидной структуре, чтобы программисты могли легко обрабатывать объект и изменять поведение приложения. 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, вы увидите древовидную структуру, то есть корневой узел - это Window, а внутри корневого узла есть только один дочерний элемент, это StackPanel. Но StackPanel содержит два дочерних элемента, кнопку и поле со списком. Окно списка имеет еще три дочерних элемента списка.
Визуальная древовидная структура
В WPF концепция визуального дерева описывает структуру визуальных объектов, представленную базовым классом Visual. Он обозначает все элементы пользовательского интерфейса, которые отображаются на экране вывода.
Когда программист хочет создать шаблон для определенного элемента управления, он фактически визуализирует визуальное дерево этого элемента управления. Визуальное дерево также очень полезно для тех, кто хочет рисовать элементы управления более низкого уровня по причинам производительности и оптимизации.
В приложениях WPF визуальное дерево используется для -
- Визуализация визуальных объектов.
- Рендеринг макетов.
- Перенаправленные события в основном перемещаются по визуальному дереву, а не по логическому дереву.
Чтобы увидеть визуальное дерево вышеупомянутого простого приложения, которое содержит кнопку и поле со списком, давайте скомпилируем и выполним код XAML, и вы увидите следующее окно.
Когда приложение запущено, вы можете увидеть визуальное дерево работающего приложения в окне Live Visual Tree, которое показывает полную иерархию этого приложения, как показано ниже.
Визуальное дерево обычно является надмножеством логического дерева. Здесь вы можете видеть, что все логические элементы также присутствуют в визуальном дереве. Таким образом, эти два дерева на самом деле представляют собой два разных представления одного и того же набора объектов, составляющих пользовательский интерфейс.
Логическое дерево не учитывает множество деталей, позволяя вам сосредоточиться на основной структуре пользовательского интерфейса и игнорировать детали того, как именно он был представлен.
Логическое дерево - это то, что вы используете для создания базовой структуры пользовательского интерфейса.
Визуальное дерево будет интересно, если вы сосредоточитесь на презентации. Например, если вы хотите настроить внешний вид любого элемента пользовательского интерфейса, вам нужно будет использовать визуальное дерево.
В приложениях WPF свойство зависимости - это особый тип свойства, расширяющий свойство CLR. Он использует преимущества определенных функций, доступных в системе свойств WPF.
Класс, определяющий свойство зависимости, должен быть унаследован от DependencyObjectкласс. Многие из классов элементов управления пользовательского интерфейса, которые используются в XAML, являются производными отDependencyObject class, и они поддерживают свойства зависимостей, например, класс 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. Когда мышь находится над кнопкой, она меняет цвет переднего плана. Когда мышь покидает кнопку, она меняет свой первоначальный цвет.
Зачем нам нужны свойства зависимостей
Свойство зависимости дает вам всевозможные преимущества, когда вы используете его в своем приложении. Свойство зависимости можно использовать поверх свойства CLR в следующих сценариях:
- Если вы хотите установить стиль
- Если вам нужна привязка данных
- Если вы хотите установить с ресурсом (статическим или динамическим)
- Если вы хотите поддержать анимацию
По сути, Dependency Properties предлагает множество функций, которые вы не получите при использовании свойства CLR.
Основное различие между dependency properties и другие CLR properties перечислены ниже -
Свойства CLR могут напрямую читать / писать из закрытого члена класса с помощью getter и setter. Напротив, свойства зависимости не хранятся в локальном объекте.
Свойства зависимостей хранятся в словаре пар ключ / значение, который предоставляется классом DependencyObject. Он также экономит много памяти, поскольку сохраняет свойство при изменении. Его также можно связать в XAML.
Настраиваемые свойства зависимостей
В .NET framework также можно определить настраиваемые свойства зависимостей. Следуйте приведенным ниже инструкциям, чтобы определить настраиваемое свойство зависимостей в C #.
Объявите и зарегистрируйте свой dependency property с регистром системных вызовов.
Обеспечьте setter и getter для собственности.
Определить static handler который будет обрабатывать любые изменения, которые происходят глобально
Определить instance handler который будет обрабатывать любые изменения, происходящие с этим конкретным экземпляром.
Следующий код 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 свойство зависимостей для пользовательского элемента управления успешно используется как текст.
А routed event- это тип события, который может вызывать обработчики для нескольких прослушивателей в дереве элементов, а не только для объекта, вызвавшего событие. По сути, это событие 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.
Укажите стратегию маршрутизации, т. Е. Пузырьковую, туннельную или прямую.
Предоставьте обработчик события.
Давайте рассмотрим пример, чтобы лучше понять настраиваемые перенаправленные события. Следуйте инструкциям, приведенным ниже -
Создайте новый проект WPF с WPFCustomRoutedEvent
Щелкните правой кнопкой мыши свое решение и выберите Добавить> Новый элемент ...
Откроется следующий диалог, теперь выберите Custom Control (WPF) и назови это MyCustomControl.
Щелкните значок Add кнопку, и вы увидите, что в ваше решение будут добавлены два новых файла (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 class который наследуется от Control class в котором создается настраиваемое перенаправленное событие 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>
Когда приведенный выше код компилируется и выполняется, он создает следующее окно, содержащее настраиваемый элемент управления.
При нажатии на настраиваемый элемент управления появится следующее сообщение.
Windows Presentation Foundation (WPF) позволяет разработчикам легко создавать и создавать визуально обогащенные приложения на основе пользовательского интерфейса.
Классические элементы пользовательского интерфейса или элементы управления в других платформах пользовательского интерфейса также улучшены в приложениях WPF.
Все стандартные элементы управления WPF можно найти на панели инструментов, которая является частью System.Windows.Controls.
Эти элементы управления также могут быть созданы на языке разметки XAML.
Полная иерархия наследования элементов управления WPF выглядит следующим образом:
В следующей таблице содержится список элементов управления, которые мы обсудим в следующих главах.
Sr. No. | Элементы управления и описание |
---|---|
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 год | Кнопка-переключатель Кнопка, которая может переключаться между 2 состояниями. |
22 | Подсказка Всплывающее окно, в котором отображается информация об элементе. |
23 | Окно Корневое окно, которое предоставляет параметр минимизации / максимизации, строку заголовка, границу и кнопку закрытия. |
24 | Сторонние средства управления Используйте сторонние элементы управления в своих приложениях WPF. |
Мы обсудим все эти элементы управления по очереди с их реализацией.
Расположение элементов управления очень важно и важно для удобства использования приложения. Он используется для организации группы элементов графического интерфейса в вашем приложении. При выборе панелей макета необходимо учитывать ряд важных моментов:
- Позиции дочерних элементов
- Размеры дочерних элементов
- Наслоение перекрывающихся дочерних элементов друг на друга
Фиксированное расположение элементов управления в пикселях не работает, когда приложение запускается на разных разрешениях экрана. XAML предоставляет богатый набор встроенных панелей макета для соответствующей организации элементов графического интерфейса. Вот некоторые из наиболее часто используемых и популярных панелей макета:
Sr. No. | Панели и описание |
---|---|
1 | Панель стека Панель стека - это простая и полезная панель макета в XAML. На панели стека дочерние элементы могут быть расположены в одну линию по горизонтали или вертикали в зависимости от свойства ориентации. |
2 | Обернуть панель В WrapPanel дочерние элементы располагаются в последовательном порядке слева направо или сверху вниз в зависимости от свойства ориентации. |
3 | Док-панель DockPanel определяет область для размещения дочерних элементов относительно друг друга по горизонтали или вертикали. С DockPanel вы можете легко закрепить дочерние элементы сверху, снизу, справа, слева и по центру, используяDock свойство. |
4 | Панель холста Панель холста - это основная панель макета, в которой дочерние элементы могут быть явно позиционированы с использованием координат, относящихся к Canvas с любой стороны, например слева, справа, сверху и снизу. |
5 | Панель сетки Панель сетки предоставляет гибкую область, состоящую из строк и столбцов. В сетке дочерние элементы могут быть расположены в табличной форме. |
Вложение макета означает использование панели макета внутри другого макета, например, определение панелей стека внутри сетки. Эта концепция широко используется для использования преимуществ нескольких макетов в приложении. В следующем примере мы будем использовать панели стека внутри сетки.
Давайте посмотрим на следующий код 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>
Когда вы скомпилируете и выполните приведенный выше код, появится следующее окно.
Мы рекомендуем вам выполнить приведенный выше пример кода и попробовать другие схемы раскроя.
Windows Presentation Foundation (WPF) предоставляет мощный API, с помощью которого приложения могут получать ввод с различных устройств, таких как мышь, клавиатура и сенсорные панели. В этой главе мы обсудим следующие типы ввода, которые могут обрабатываться в приложениях WPF:
Sr. No. | Входы и описание |
---|---|
1 | Мышь Существуют различные типы ввода с помощью мыши, такие как MouseDown, MouseEnter, MouseLeave и т. Д. |
2 | Клавиатура Существует множество типов ввода с клавиатуры, таких как KeyDown, KeyUp, TextInput и т. Д. |
3 | ContextMenu или RoutedCommands RoutedCommands позволяет обрабатывать ввод на более семантическом уровне. На самом деле это простые инструкции: «Создать», «Открыть», «Копировать», «Вырезать» и «Сохранить». |
4 | Мультитач Windows 7 и более поздние версии имеют возможность получать ввод с нескольких сенсорных устройств. Приложения WPF также могут обрабатывать сенсорный ввод как другой ввод, такой как мышь или клавиатура, путем создания событий при касании. |
Аргумент командной строки - это механизм, с помощью которого пользователь может передать набор параметров или значений приложению WPF при его выполнении. Эти аргументы очень важны для управления приложением извне, например, если вы хотите открыть документ Word из командной строки, вы можете использовать эту команду «C:\> start winword word1.docx»И он откроется word1.docx документ.
Аргументы командной строки обрабатываются в функции запуска. Ниже приведен простой пример, показывающий, как передавать аргументы командной строки в приложение WPF. Создадим новое приложение WPF с именемWPFCommandLine.
Перетащите одно текстовое поле из панели инструментов в окно дизайна.
В этом примере мы передадим нашему приложению путь к 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, которое получит аргументы командной строки.
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 программа откроет текстовый файл и напишет весь текст в текстовое поле.
Если обнаружена какая-то ошибка, программа отобразит сообщение об ошибке в текстовом поле.
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 в проводнике решений и выберите свойства, откроется следующее окно.
Выберите параметр «Отладка» и укажите путь к файлу в аргументе командной строки.
Создайте текстовый файл с Test.txt, напишите в него текст и сохраните его в любом месте. В этом случае текстовый файл сохраняется на «D:\" жесткий диск.
Сохраните изменения в своем проекте, скомпилируйте и запустите приложение прямо сейчас. Вы увидите текст в TextBox, который программа читает из файла Text.txt.
Теперь давайте попробуем изменить имя файла на вашем компьютере с Test.txt к Test1.txt и снова запустите вашу программу, тогда вы увидите это сообщение об ошибке в текстовом поле.
Мы рекомендуем вам выполнить приведенный выше код и выполнить все шаги для успешного выполнения вашего приложения.
Связывание данных - это механизм в приложениях WPF, который обеспечивает простой и легкий способ для приложений среды выполнения Windows отображать данные и взаимодействовать с ними. В этом механизме управление данными полностью отделено от способа передачи данных.
Связывание данных позволяет поток данных между элементами пользовательского интерфейса и объектом данных в пользовательском интерфейсе. Когда привязка установлена и данные или ваша бизнес-модель изменяются, она автоматически отражает обновления элементов пользовательского интерфейса и наоборот. Также можно выполнить привязку не к стандартному источнику данных, а к другому элементу на странице.
Привязка данных бывает двух типов - one-way data binding и two-way data binding.
Односторонняя привязка данных
При односторонней привязке данные привязываются от своего источника (то есть объекта, который хранит данные) к своей цели (то есть объекту, который отображает данные)
Давайте рассмотрим простой пример, чтобы подробно разобраться в односторонней привязке данных. Прежде всего, создайте новый проект 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>
Текстовые свойства обоих текстовых полей привязаны к «Name» и «Age», которые являются переменными класса класса Person, который показан ниже.
В классе 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.
Когда вы нажимаете Show кнопку, имя и возраст отобразятся в окне сообщения.
Давайте изменим Имя и Возраст в диалоговом окне.
Если вы сейчас нажмете кнопку «Показать», снова отобразится то же сообщение.
Это связано с тем, что в коде 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>
Давайте снова запустим это приложение.
Он будет производить тот же результат -
Теперь изменим значения Name и Age -
Если сейчас нажать кнопку «Показать», отобразится обновленное сообщение.
Мы рекомендуем вам выполнить приведенный выше код в обоих случаях для лучшего понимания концепции.
Ресурсы - это обычно определения, связанные с каким-либо объектом, который вы ожидаете использовать чаще одного раза. Это возможность хранить данные локально для элементов управления или для текущего окна или глобально для всех приложений.
Определение объекта как ресурса позволяет нам получить к нему доступ из другого места. Это означает, что объект можно использовать повторно. Ресурсы определяются в словарях ресурсов, и любой объект может быть определен как ресурс, что фактически делает его совместно используемым активом. Для ресурса XAML указывается уникальный ключ, и с этим ключом на него можно ссылаться с помощью расширения разметки StaticResource.
Ресурсы могут быть двух типов -
- StaticResource
- DynamicResource
StaticResource - это одноразовый поиск, тогда как DynamicResource больше похож на привязку данных. Он помнит, что свойство связано с конкретным ключом ресурса. Если объект, связанный с этим ключом, изменяется, динамический ресурс обновит целевое свойство.
пример
Вот простое приложение для ресурса SolidColorBrush.
Создадим новый проект 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.
Когда вы нажмете кнопку «Изменить ресурс», вы увидите, что прямоугольник с DynamicResource изменит свой цвет на красный.
Объем ресурсов
Ресурсы определены в resource dictionaries, но есть множество мест, где можно определить словарь ресурсов. В приведенном выше примере словарь ресурсов определяется на уровне окна / страницы. В каком словаре определяется ресурс, сразу же ограничивается область действия этого ресурса. Таким образом, объем, то есть где вы можете использовать ресурс, зависит от того, где вы его определили.
Определите ресурс в словаре ресурсов сетки, и он будет доступен только этой сетке и ее дочерним элементам.
Определите его в окне / странице, и он будет доступен для всех элементов этого окна / страницы.
Корень приложения можно найти в словаре ресурсов App.xaml. Это корень нашего приложения, поэтому ресурсы, определенные здесь, относятся ко всему приложению.
Что касается объема ресурса, то чаще всего это уровень приложения, уровень страницы и уровень конкретного элемента, например Grid, StackPanel и т. Д.
Вышеупомянутое приложение имеет ресурсы на уровне окна / страницы.
Словари ресурсов
Словари ресурсов в приложениях XAML подразумевают, что словари ресурсов хранятся в отдельных файлах. Это соблюдается почти во всех приложениях XAML. Определение ресурсов в отдельных файлах может иметь следующие преимущества:
Разделение между определением ресурсов в словаре ресурсов и кодом, связанным с пользовательским интерфейсом.
Определение всех ресурсов в отдельном файле, таком как App.xaml, сделает их доступными для всего приложения.
Итак, как нам определить наши ресурсы в словаре ресурсов в отдельном файле? Что ж, это очень просто, просто добавьте новый словарь ресурсов через Visual Studio, выполнив следующие шаги:
В своем решении добавьте новую папку и назовите ее ResourceDictionaries.
Щелкните эту папку правой кнопкой мыши, выберите «Словарь ресурсов» в пункте подменю «Добавить» и назовите его. 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 вы можете легко создавать свои собственные шаблоны, если хотите настроить визуальное поведение и внешний вид элемента управления.
Связь между логикой и шаблоном может быть достигнута путем привязки данных. Основное различие междуstyles и templates перечислены ниже -
Стили могут изменять только внешний вид вашего элемента управления со свойствами этого элемента управления по умолчанию.
С помощью шаблонов вы можете получить доступ к большему количеству частей элемента управления, чем в стилях. Вы также можете указать как существующее, так и новое поведение элемента управления.
Чаще всего используются два типа шаблонов:
- Шаблон управления
- Шаблон данных
Шаблон управления
Шаблон элемента управления определяет внешний вид элемента управления. Все элементы пользовательского интерфейса имеют некоторый вид, а также поведение, например, Button имеет внешний вид и поведение. Событие щелчка или событие наведения мыши - это поведение, которое запускается в ответ на щелчок и наведение, а также есть внешний вид кнопки по умолчанию, который можно изменить с помощью шаблона элемента управления.
пример
Возьмем простой пример. Мы создадим две кнопки (одна с шаблоном, а другая - кнопка по умолчанию) и инициализируем их некоторыми свойствами.
<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 мы создадим шаблон данных как ресурс для хранения меток и текстовых полей. Также есть кнопка и список для отображения данных.
<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>
Вот это implementation in 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, которые отображаются в полях «Ярлыки» и «Текст».
Платформа .NET предоставляет несколько стратегий для персонализации и настройки внешнего вида приложения. Стили предоставляют нам гибкость в установке некоторых свойств объекта и повторном использовании этих конкретных настроек для нескольких объектов для единообразного внешнего вида.
В стилях вы можете установить только существующие свойства объекта, такие как Высота, Ширина, Размер шрифта и т. Д.
Можно указать только поведение элемента управления по умолчанию.
В один стиль можно добавить несколько свойств.
Стили используются для придания единообразного вида или внешнего вида набору элементов управления. Неявные стили используются для применения внешнего вида ко всем элементам управления заданного типа и упрощения приложения. Представьте себе три кнопки, все они должны выглядеть одинаково, иметь одинаковую ширину и высоту, одинаковый размер шрифта, один и тот же цвет переднего плана и т. Д. Мы можем установить все эти свойства на самих элементах кнопки, и это все еще нормально для всех кнопок. Взгляните на следующую диаграмму.
Но в реальных приложениях их обычно гораздо больше, и они должны выглядеть точно так же. И не только кнопки, конечно, вы обычно хотите, чтобы ваши текстовые блоки, текстовые поля, поля со списком и т. Д. Выглядели одинаково во всем приложении. Конечно, должен быть лучший способ добиться этого, и он известен какstyling. Вы можете думать о стиле как о удобном способе применения набора значений свойств к нескольким элементам. Взгляните на следующую диаграмму.
пример
Давайте рассмотрим простой пример, чтобы понять эту концепцию. Начните с создания нового проекта WPF.
Перетащите три кнопки с панели инструментов в окно дизайна.
Следующий код 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>
Когда вы посмотрите на приведенный выше код, вы увидите, что для всех кнопок высота, ширина, цвет переднего плана, размер шрифта и свойства полей одинаковы. Теперь, когда приведенный выше код скомпилирован и выполнен, отобразится следующее окно.
Теперь давайте посмотрим на тот же пример, но на этот раз мы будем использовать style.
<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> вы можете видеть, что для каждого свойства, которое будет включено в стиль, определено несколько тегов-установщиков.
В приведенном выше примере все общие свойства каждой кнопки теперь определены в стиле, а затем стиль назначается каждой кнопке с уникальным ключом путем установки свойства стиля с помощью расширения разметки StaticResource.
Когда вы скомпилируете и выполните приведенный выше код, он отобразит следующее окно (тот же результат).
Преимущество такого подхода сразу же очевидно, мы можем повторно использовать этот стиль в любом месте его действия; и если нам нужно изменить его, мы просто меняем его один раз в определении стиля, а не на каждом элементе.
На каком уровне определяется стиль, мгновенно ограничивается его область применения. Таким образом, область действия, то есть где вы можете использовать стиль, зависит от того, где вы его определили. Стили можно определять на следующих уровнях -
Старший Нет | Уровни и описание |
---|---|
1 | Уровень контроля Определение стиля на уровне элемента управления может применяться только к этому конкретному элементу управления. Ниже приведен пример уровня управления, на котором кнопка и TextBlock имеют свой собственный стиль. |
2 | Уровень макета Определение стиля на любом уровне макета сделает его доступным только для этого макета и его дочерних элементов. |
3 | Уровень окна Определение стиля на уровне окна может сделать его доступным для всех элементов этого окна. |
4 | Уровень приложения Определение стиля на уровне приложения может сделать его доступным для всего приложения. Возьмем тот же пример, но здесь мы поместим стили в файл app.xaml, чтобы сделать его доступным для всего приложения. |
Триггер в основном позволяет вам изменять значения свойств или предпринимать действия в зависимости от значения свойства. Таким образом, он позволяет вам динамически изменять внешний вид и / или поведение вашего элемента управления без необходимости создавать новый.
Триггеры используются для изменения значения любого заданного свойства при выполнении определенных условий. Триггеры обычно определяются в стиле или в корне документа, которые применяются к этому конкретному элементу управления. Есть три типа триггеров -
- Триггеры свойств
- Триггеры данных
- Триггеры событий
Триггеры свойств
В триггерах свойств, когда изменение происходит в одном свойстве, оно вызывает немедленное или анимированное изменение другого свойства. Например, вы можете использовать триггер свойства, чтобы изменить внешний вид кнопки при наведении курсора мыши на кнопку.
В следующем примере кода показано, как изменить цвет переднего плана кнопки при наведении указателя мыши на кнопку.
<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>
Когда вы скомпилируете и выполните приведенный выше код, он выдаст следующее окно:
После нажатия кнопки вы увидите, что она начнет расширяться в обоих измерениях.
Мы рекомендуем вам скомпилировать и выполнить приведенные выше примеры, а также применить триггеры к другим свойствам.
Это систематический механизм выявления и исправления ошибок или дефектов в фрагменте кода, который ведет себя не так, как вы ожидаете. Отладка сложного приложения, в котором подсистемы тесно связаны, не так проста, потому что исправление ошибок в одной подсистеме может создать ошибки в другой подсистеме.
Отладка на 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 value с другими значениями, поэтому программа вылетает.
Отладка в XAML
Если вы ожидаете такой же отладки в XAML, вы будете удивлены, узнав, что отладка кода XAML, как отладка любого другого кода процедурного языка, пока невозможна. Когда вы слышите термин «отладка» в коде XAML, это означает «попытаться найти ошибку».
При привязке данных ваши данные не отображаются на экране, и вы не знаете, почему
Или проблема связана со сложными макетами.
Или проблема с выравниванием, или проблемы с цветом полей, наложениями и т. Д. С некоторыми обширными шаблонами, такими как 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' не найдено в 'object' '' 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, где все элементы показаны в виде дерева.
Это живое визуальное дерево показывает полную структуру макета, чтобы понять, где расположены элементы пользовательского интерфейса. Но эта опция доступна только в Visual Studio 2015. Если вы используете более старую версию Visual Studio, вы не можете использовать этот инструмент, однако есть другой инструмент, который можно интегрировать с Visual Studio, например XAML Spy для Visual Studio. . Вы можете скачать его с xamlspy
Приложения WPF позволяют создавать настраиваемые элементы управления, что упрощает создание многофункциональных и настраиваемых элементов управления. Пользовательские элементы управления используются, когда все встроенные элементы управления, предоставленные Microsoft, не соответствуют вашим критериям или вы не хотите платить за сторонние элементы управления.
В этой главе вы узнаете, как создавать собственные элементы управления. Прежде чем мы начнем рассматривать настраиваемые элементы управления, давайте сначала кратко рассмотрим пользовательский элемент управления.
Пользовательский контроль
Пользовательские элементы управления предоставляют способ собирать и комбинировать различные встроенные элементы управления вместе и упаковывать их в повторно используемый XAML. Пользовательские элементы управления используются в следующих сценариях -
Если элемент управления состоит из существующих элементов управления, то есть вы можете создать один элемент управления из нескольких уже существующих элементов управления.
Если элементу управления не нужна поддержка тем. Пользовательские элементы управления не поддерживают сложные настройки, шаблоны элементов управления и сложные стили.
Если разработчик предпочитает писать элементы управления с использованием модели кода программной части, в которой отображается представление, а затем прямой код для обработчиков событий.
Вы не будете делиться своим контролем между приложениями.
пример
Давайте перейдем к примеру управления пользователем и выполним шаги, указанные ниже.
Создайте новый проект WPF, затем щелкните правой кнопкой мыши свое решение и выберите Добавить> Новый элемент ...
Откроется следующее окно. Теперь выберитеUser Control (WPF) и назовите его MyUserControl.
Нажмите кнопку «Добавить», и вы увидите, что в ваше решение будут добавлены два новых файла (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>
Когда вы скомпилируете и выполните приведенный выше код, появится следующее окно.
После нажатия кнопки «Click Me» вы заметите, что текст внутри текстового поля обновлен.
Пользовательские элементы управления
Пользовательский элемент управления - это класс, который предлагает свой собственный стиль и шаблон, которые обычно определены в 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>
Когда вы скомпилируете и выполните приведенный выше код, он создаст следующее окно с настраиваемым элементом управления, который представляет собой настраиваемую кнопку.
Нажав настроенную кнопку, вы увидите, что текст внутри текстового блока обновлен.
Исключением является любое состояние ошибки или неожиданное поведение, возникающее во время выполнения программы. Исключения могут возникать по многим причинам, некоторые из них следующие:
Ошибка в вашем коде или в коде, который вы вызываете (например, в общей библиотеке),
Недоступные ресурсы операционной системы,
Неожиданные условия, с которыми сталкивается среда CLR (например, код, который невозможно проверить)
Синтаксис
Исключения имеют возможность передавать поток программы из одной части в другую. В .NET framework обработка исключений имеет следующие четыре ключевых слова:
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 прямо или косвенно являются производными от класса Exception. Наиболее важные классы исключений, производные от класса Exception:
ApplicationException class- Он поддерживает исключения, которые генерируются программами. Когда разработчик хочет определить исключение, класс должен быть производным от этого класса.
SystemException class- Это базовый класс для всех предопределенных исключений системы времени выполнения. Следующая иерархия показывает стандартные исключения, предоставляемые средой выполнения.
В следующей таблице перечислены стандартные исключения, предоставляемые средой выполнения, и условия, при которых следует создать производный класс.
Тип исключения | Базовый тип | Описание |
---|---|---|
Exception | Объект | Базовый класс для всех исключений. |
SystemException | Исключение | Базовый класс для всех ошибок времени выполнения. |
IndexOutOfRangeException | SystemException | Выдается средой выполнения только в том случае, если массив неправильно проиндексирован. |
NullReferenceException | SystemException | Выдается средой выполнения только при ссылке на нулевой объект. |
AccessViolationException | SystemException | Выбрасывается средой выполнения только при обращении к недопустимой памяти. |
InvalidOperationException | SystemException | Выбрасывается методами в недопустимом состоянии. |
ArgumentException | SystemException | Базовый класс для всех исключений аргументов. |
ArgumentNullException | ArgumentException | Вызывается методами, которые не позволяют аргументу иметь значение NULL. |
ArgumentOutOfRangeException | ArgumentException | Вызывается методами, которые проверяют, находятся ли аргументы в заданном диапазоне. |
ExternalException | 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();
}
}
}
}
}
Когда при выполнении вышеуказанного кода возникает исключение, отображается следующее сообщение.
Мы рекомендуем вам выполнить приведенный выше код и поэкспериментировать с его функциями.
Локализация - это перевод ресурсов приложения в локализованные версии для определенных культур, которые поддерживает приложение.
Когда вы разрабатываете свое приложение и оно доступно только на одном языке, вы ограничиваете количество своих клиентов и размер своего бизнеса. Если вы хотите увеличить свою клиентскую базу, что также приведет к росту вашего бизнеса, тогда ваш продукт должен быть доступен и доступен для глобальной аудитории. Экономически эффективнымlocalization вашего продукта - один из лучших и наиболее экономичных способов привлечь больше клиентов.
В WPF легко создавать локализуемые приложения с помощью resxфайл, который является самым простым решением для локализации. Давайте рассмотрим простой пример, чтобы понять, как это работает -
Создайте новый проект WPF с именем WPFLocalization.
В проводнике решений вы увидите файл Resources.resx в папке «Свойства».
Измените модификатор доступа с внутреннего на общедоступный, чтобы он был доступен в файле XAML.
Теперь добавьте имя и значения следующей строки, которые мы будем использовать в нашем приложении.
Сделайте две копии файла Resources.resx с именами Resources.en.resx и Resources.ru-RU.resx. Это соглашения об именах, характерные для языка и названия страны / региона, и их можно найти в Справочнике по API поддержки национальных языков (NLS) (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, в котором элементы управления создаются и инициализируются с разными свойствами.
<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, как показано ниже.
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 взаимодействие показывает, как представление взаимодействует с элементами управления, расположенными в этом представлении. Наиболее известные взаимодействия бывают двух типов:
- Behaviors
- Перетащить и отпустить
Поведение
Поведение было введено в Expression Blend 3, который может инкапсулировать некоторые функции в повторно используемый компонент. Чтобы добавить дополнительные варианты поведения, вы можете прикрепить эти компоненты к элементам управления. Поведение обеспечивает большую гибкость для простого проектирования сложных взаимодействий с пользователем.
Давайте посмотрим на простой пример, в котором поведение ControlStoryBoardAction прикреплено к элементам управления.
Создайте новый проект 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.
<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 # для перетаскивания.
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 поддерживает объекты Drawing и Shape, которые используются для рисования графического содержимого.
Формы и рисунок
Класс Shape является производным от класса FrameworkElement, объекты Shape могут использоваться внутри панелей и большинства элементов управления.
WPF предоставляет некоторые базовые объекты формы, которые являются производными от класса Shape, например Ellipse, Line, Path, Polygon, Polyline и Rectangle.
С другой стороны, объекты рисования не являются производными от класса FrameworkElement и обеспечивают более легкую реализацию.
Объекты рисования проще по сравнению с объектами формы. У них также лучшие рабочие характеристики.
пример
Давайте рассмотрим простой пример, чтобы понять, как использовать объекты различной формы.
Создайте новый проект 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 показано, как рисовать изображения по-другому.
<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-фигур и рисунков.
Windows Presentation Foundation (WPF) предоставляет функциональные возможности для рисования, преобразования и анимации трехмерной графики в соответствии с требованиями вашего приложения. Он не поддерживает полноценную разработку 3D-игр, но на определенном уровне вы можете создавать 3D-графику.
Комбинируя двухмерную и трехмерную графику, вы также можете создавать многофункциональные элементы управления, предоставлять сложные иллюстрации данных или повышать удобство использования интерфейса приложения. Элемент Viewport3D размещает 3D-модель в нашем приложении WPF.
пример
Давайте рассмотрим простой пример, чтобы понять, как использовать 3D-графику.
Создайте новый проект WPF с именем WPF3DGraphics.
Следующий код XAML показывает, как создать 2D-объект с использованием 3D-геометрии.
<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.
пример
Давайте посмотрим на другой пример, который показывает трехмерный объект.
Создайте новый проект 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-объект и слайдер в вашем окне.
Когда вы перемещаете ползунок, объект в вашем окне также будет вращаться.
Мы рекомендуем вам выполнить приведенный выше код и попробовать больше трехмерной геометрии.
Приложения WPF поддерживают видео и аудио с помощью MediaElement. Он позволяет интегрировать аудио и видео в приложение. Класс MediaElement работает аналогично классу Image. Вы просто указываете им на средства массовой информации, и они это воспроизводят. Основное отличие состоит в том, что это будет движущееся изображение, но если вы укажете его на файл, который содержит только звук и не содержит видео, например MP3, он будет воспроизводить его, ничего не показывая на экране.
WPF поддерживает все типы видео / аудиоформатов в зависимости от конфигурации машины. Если медиафайл воспроизводится в проигрывателе мультимедиа, он также будет работать в WPF на том же компьютере.
пример
Давайте рассмотрим пример, чтобы понять, как интегрировать мультимедиа в ваше приложение.
Создайте новый проект 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 класс на работу.
Щелкните правой кнопкой мыши Ссылки и выберите Добавить ссылку.
Откроется диалоговое окно «Диспетчер ссылок». Теперь установите флажок System.Speech.
Щелкните кнопку ОК. Вы можете увидеть сборку System.Speech в своих Справочниках.
Теперь перетащите кнопку и текстовое поле в окно дизайна из панели инструментов.
Следующий код 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 #, которая преобразует текст внутри текстового поля в произносимые слова.
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». Если вы ничего не вводите в текстовое поле, появится следующее сообщение.
Мы рекомендуем вам выполнить приведенные выше примеры.