XAML 2009
26WPF --- Основа WPF --- XAML 2009
В WPF 4 появился новый стандарт под названием XAML 2009. Однако пока он не внедрен повсеместно. Чтобы получить преимущества XAML 2009 в настоящее время, необходимо использовать несвязанные, не скомпилированные файлы XAML, что не удовлетворяет большинство разработчиков.
Даже если вы решите не использовать XAML 2009, стоит кратко познакомиться с его средствами. Дело в том, что в конечном итоге в следующей версии WPF язык XAML 2009 превратится в полностью интегрированный скомпилированный стандарт. Имейте в виду, что средство IntelliSense в Visual Studio пометит некоторые из них как ошибки времени проектирования, потому что пока производится проверка кода на предмет соответствия существующему стандарту XAML. Однако во время выполнения они будут работать должным образом.
Автоматическая привязка событий
В показанном ранее примере несвязанного XAML в коде требовалось вручную подключать обработчики событий, а это означает, что код должен обладать детальными сведениями о содержимом файла XAML (таком как имена всех элементов, инициирующих события, которые необходимо обрабатывать).
Стандарт XAML 2009 предлагает частичное решение проблемы. Его анализатор может автоматически подключать обработчики событий, если соответствующие методы-обработчики определены в корневом классе. Например, рассмотрим следующую разметку:
<Window
xmlns="http://schemas.microsoft.com/winfх/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<Button Click="cmd_Click"></Button>
</StackPanel>
</Window>
Если передать этот документ методу XamlReader.Load(), возникнет ошибка, потому что метод Window.cmd_Click() не существует. Но если создать собственный специальный класс, унаследованый от Window, скажем, XAML 2009Window, и применить показанную ниже разметку:
<local:XAML 2009Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:NonCompiledXaml;assembly=NonCompiledXaml">
<StackPanel>
<Button Click="cmd_Click"></Button>
</StackPanel>
</local:XAML 2009Window>
то анализатор сможет создать экземпляр класса XAML 2009Window и затем присоединит к событию Button.Click метод XAML 2009Window.cmd_Click() автоматически. Эта техника отлично работает с приватными методами, но если метод не существует (или не имеет правильной сигнатуры), генерируется исключение.
Вместо загрузки XAML в конструкторе (как в предыдущем примере) класс XAML 2009Window использует собственный статический метод по имени LoadWindowFromXaml(). Такое проектное решение несколько лучше, потому что подчеркивает потребность в нетривиальном процессе, который необходим для создания объекта окна — в данном случае это открытие файла. При этом также можно организовать более ясную обработку исключений, если код не найдет или не получит доступа к файлу XAML. Причина в том, что генерировать исключение имеет больший смысл в методе, чем в конструкторе.
Возможно, вы уже заметили, что эта модель довольно похожа на встроенную модель Visual Studio, которая компилирует XAML. В обоих случаях весь код обработки событий помещается в специальный класс, унаследованный от элемента, который действительно нужен (обычно Window или Page).
Ссылки
В обычном языке XAML не существует простого способа ссылки одного элемента на другой. Лучшее решение состоит в привязке данных, но для простых сценариев это слишком громоздко. В XAML 2009 задача упрощается за счет расширения разметки, которое специально предназначено для ссылок.
В следующих двух фрагментах разметки показаны две ссылки, используемые для установки свойства Target объектов Label. Свойство Label.Target указывает на элемент управления вводом, который принимает фокус, когда пользователь нажимает горячую клавишу. В данном примере первое текстовое поле использует комбинацию <Alt+F>. Если пользователь нажимает эту комбинацию клавиш, фокус переходит к элементу управления txtFirstName, определенному следом:
<Label Target="{x:Reference txtFirstName}">_FirstName</Label>
<TextBox x:Name="txtFirstName"></ТехtBox>
<Label Target="{x:Reference txtLastName}">_LastName</Label>
<TextBox x:Name="txtLastName"></TextBox>
Встроенные типы
Как уже известно, разметка XAML может обращаться почти к любому пространству имен, если сначала отобразить его на пространство имен XML. Многие новички в WPF удивляются, когда узнают о необходимости ручного отображения пространств имен для использования базовых типов из пространства System, таких как String, DateTime, TimeSpan, Boolean, Char, Decimal, Single, Double, Int32, Uri, Byte и т.д. Хотя это относительно небольшое препятствие, все же оно требует дополнительного шага с вашей стороны и привносит дополнительную путаницу.
В XAML 2009 пространство имен XAML обеспечивает прямой доступ к этим типам данных, не требуя никаких излишних усилий:
<x:String>A String</x:String>
Можно также напрямую обращаться к обобщенным типам коллекций List и Dictionary.
При установке свойств элементов управления WPF данная проблема не возникает. Это объясняется тем, что конвертер значений берет строку и преобразует ее в соответствующий тип данных автоматически, как объяснялось ранее. Однако бывают ситуации, когда конвертеры значений не работают, и нужны специфические типы данных. Одним из примеров может быть необходимость в применении простых типов данных для хранения ресурсов — объектов, которые можно многократно использовать в разметке и коде.
Расширенное создание объектов
Обычный язык XAML позволяет создавать объект почти любого типа - при условии, что у него имеется конструктор без аргументов. В XAML 2009 это ограничение снято и предлагаются два более мощных способа создания и инициализации объектов. Первый из них - возможность использования элемента <x:Arguments> для передачи аргументов конструктору.
Второй подход предусматривает применение статического метода (того же, либо другого класса), который создает необходимый объект. Этот шаблон называется фабричным методом. Пример фабричного метода содержит класс Guid из пространства имен System, представляющий глобально уникальный идентификатор.
Создать экземпляр Guid с помощью ключевого слова new нельзя, но можно вызвать метод Guid.NewGuid(), который вернет новый экземпляр.
В XAML 2009 аналогичный прием можно использовать в разметке. Секрет кроется в атрибуте x:FactoryMethod.
XAML 2009 также позволяет создавать экземпляры обобщенных коллекций, что в обычном XAML невозможно. (Хотя существует обходной путь — унаследовать специальный класс коллекции для использования в качестве оболочки и создать его экземпляр в XAML. Однако это быстро засорит код излишними одноразовыми классами.) В XAML 2009 атрибут TypeArguments предоставляет возможность передачи аргументов обобщенному классу.