Читайте также: |
|
Язык XAML обладает дополнительной по сравнению с XML семантикой, которая допускает единую интерпретацию. Слегка упрощая, можно сказать, что XAML - это основанный на XML сценарный язык для создания объектов CLR. Имеется соответствие межу XML-тегами и типами CLR, а также между XML-атрибутами и свойствами и событиями CLR. В следующем примере показано, как создать объект и присвоить значение его свойству на языках XAML и C#:
<!— версия на XAML —>
<MyObject SomeProperty='1' />
// версия на C#
MyObject obj = new MyObject();
obj.SomeProperty = 1;
XML-теги всегда определяются в контексте некоторого пространства имен, которое и описывает, какие теги являются допустимыми. В XAML пространства имен в смысле XML отображаются на наборы пространств имен и сборок в смысле CLR. Чтобы приведенный выше простой пример заработал, необходимо установить соответствие между требуемыми пространствами имен. В XML для определения новых пространств имен применяется атрибут xmlns:
<!— версия для XAML —>
<MyObject xmlns='clr-namespace:Samples' SomeProperty='1' />
// версия для C# using Samples;
MyObject obj = new MyObject();
obj.SomeProperty = 1;
В C# перечень сборок, в которых находятся используемые типы, всегда задается в файле проекта или с помощью аргументов командной строки для запуска компилятора csc.exe. В XAML можно определить местоположение исходной сборки для каждого пространства имен:
<!— версия для XAML —>
<MyObject xmlns='clr-namespace:Samples; assembly=samples.dll'
SomeProperty='1'/>
// версия для C#
csc /r:samples.dll test.cs
using Samples;
MyObject obj = new MyObject();
obj.SomeProperty = 1;
В XML мир разбит на две половины: элементы и атрибуты. Модель XAML более тесно связана с CLR, поскольку апеллирует к объектам, свойствам и событиям. Значения свойств можно представлять в виде атрибутов или дочерних элементов. Предыдущий пример допустимо записать и так:
<MyObject xmlns='clr-namespace:Samples, assembly=samples.dll'>
<MyObject.SomeProperty>
</MyObject.SomeProperty>
</MyObject>
Каждый элемент, соответствующий свойству, квалифицируется типом, которому это свойство принадлежит. Предположим, например, что есть еще одно свойство, значением которого является объект типа Person со свойствами FirstName и LastName. На XAML можно было бы легко выразить это соотношение, воспользовавшись элементами для описания свойств:
<MyObject xmlns='clr-namespace:Samples, assembly=samples.dll'>
<MyObject.Owner>
<Person FirstName='Chris' LastName='Anderson' />
</MyObject.Owner>
</MyObject>
XAML проектировался как язык разметки, тесно интегрированный с CLR и обеспеченный развитой инструментальной поддержкой. Дополнительно ставилась цель создать такой формат, который было бы легко читать и записывать. Может показаться, что проектировать свойство платформы, которое оптимизировано прежде всего для инструментов, а лишь потом для людей, не слишком вежливо, но команда WPF полагала, что приложения для WPF как правило будут создавать с помощью таких программ визуального конструирования, как Microsoft Visual Studio или Microsoft Expression. Чтобы граница между инструментами и людьми не была непроходимой, WPF позволяет автору типу определить одно свойство как контентное.[1]
В примере выше, если сделать свойство Owner типа MyObject контентным[2], то в разметке можно будет опустить тег элемента, соответствующего этому свойству:
<MyObject xmlns='clr-namespace:Samples; assembly=samples.dll'>
<Person FirstName='Megan' LastName='Anderson' />
</MyObject>
Чтобы воспринимать текст было еще удобнее, в XAML есть возможность расширения разметки. Это общий способ расширить синтаксический анализатор языка с целью создания более простой разметки. Расширения реализуются в виде типов CLR и работают почти так же, как атрибуты CLR. Они заключаются в фигурные скобки { }. Например, чтобы присвоить свойству специальное значение null, можно воспользоваться встроенным расширением разметки Null:
<MyObject xmlns='clr-namespace:Samples; assembly=samples.dll'>
<Person FirstName='Megan' LastName='{x:Null}'/>
</MyObject>
В таблице 1.1 перечислены все встроенные расширения XAML.
Таблица 1.1. Встроенные расширения XAML
Пространство имен XAML | Назначение | Пример |
x:Array | Создает массив CLR | <x:Array Type='{x:Type Button}'> <Button /> <Button /> </x:Array> |
x:Class | Задает имя определяемого типа (используется только при компиляции разметки) | <Window x:Class = 'MyNamespace.MyClass '> ... </Window> |
X:ClassModifier | Задает модификаторы определяемого типа («public» «intemal» и т.д.) (используется только при компиляции разметки) | <Window x:Class='...' x:ClassModifier='Public'> </Window> |
x:Code | Ограничивает блок встроенного кода (используется только при компиляции разметки) | <Window x:Class='...'> <x:Code> public void DoSomething() { } </x:Code> </Window> |
x:Key | Задает ключ элемента (поддерживается только для элементов, содержащихся в словарях) | <Button> <Button.Resources> <Style x:Key='Hi'>...</Style> </Button.Resources> </Button> |
x:Name | Задает имя элемента для ссылки на него в программе (обычно используется, когда у элемента нет встроенного свойства name) | <sys:Int32 xmlns:sys = 'clr-namespace: System;...' x:Name = '_myIntegerValue'> 5 </sys:Int32> |
x:Null | Создает значение | null. <Button Content = '{x:Null}' /> |
x:Static | Создает значение путем доступа к статическому полю или свойству типа. | <Button Command = '{x:Static ApplicationCommands.Close}' /> |
x:Subclass | Предоставляет базовый тип для компиляции разметки на язык, в котором не поддерживаются частичные типы. | |
x:Type | Предоставляет тип CLR (эквивалент Type.GetType). | <ControlTemplate TargetType='{x:Type Button}'> </ControlTemplate> |
x:TypeArguments | Задает обобщенные аргументы типа для создания экземпляра обобщенного типа. | <gc:List xmlns:gc='clrnamespace: System.Collections.Generic;...' |
x:TypeArguments ='{x:Type Button}'/> x:XData | Ограничивает блок встроенного XML; может использоваться только для свойств типа IXmlSerializable. | <XmlDataSource> <x:XData> <Book xmlns=" Title='...' /> </x:XData> </XmlDataSource> |
Расширения разметки ищутся точно так же, как теги объектов, то есть необходимо объявить XML-префикс «x», иначе синтаксический анализатор выдаст ошибку. В языке XAML определено специальное пространство имен для встроенных типов:
<MyObject
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns='clr-namespace:Samples,-asserrbly=samples.dll'>
<Person FirstName='Megan' LastName='{x:Null}' />
</MyObject>
Кроме того, для любой сборки CLR (или набора таких сборок) можно определить имя, построенное по принципу URI и соответствующее пространствам имен и сборок CLR. Это можно считать эквивалентом старого доброго предложения #include 'windows.h', которое хорошо известно программистам на C/C++. В сборках WPF этот механизм применяется, поэтому для импорта WPF в XAML-файл можно использовать любой формат:
<!— вариант 1: импорт по пространству имен CLR —>
<Window
xmlns:x='http://schemas.microsoft.com/winfx/2 0 06/xaml'
xmlns='clr-namespace:System.Windows;assembly=presentationframework.dll'>
</Window>
<!— вариант 2: импорт по URI —>
<Window
xmlns:x='http://schemas.microsoft.com/winfx/2 0 06/xaml'
xmlns='http://schemas.microsoft.com/winfx/2 006/xaml/presentation'>
</Window>
Метод с применением синтаксиса URI хорош тем, что импортируются сразу несколько пространств имен и сборок CLR, а, значит, разметка получается более компактной и работать с ней проще.
В завершении лекции, нужно сказать о такой возможности XAML, как способность расширять типы за счет свойств, предоставляемых другими типами. Такие присоединенные свойства - это просто безопасный относительно типов вариант добавленных свойств (expando properties) в языке JavaScript. В версии XAML, предназначенной для WPF, присоединенные свойства работают только, если и тип, в котором свойство определено, и тип, к которому оно присоединяется, наследуют классу DependencyObject. Однако в общей спецификации XAML такого требования нет.
В следующем примере свойство Dock определено в типе DockPanel. Присоединенному свойству всегда предшествует имя предоставляющего его типа, даже если такое свойство употребляется в качестве атрибута:
<Window
xmlns:x='http://schemas.microsoft.com/winfx/2 0 06/xaml'
xmlns='http://schemas.microsoft.com/winfx/2 006/xaml/presentation'>
<DockPanel>
<Button DockPanel.Dock='Top'>Top</Button>
<Button>
<DockPanel.Dock>Left</DockPanel.Dock>
Left
</Button>
<Button>Fill</Button>
</DockPanel>
</Window>
XAML - довольно простой язык, в нем не очень много правил. В версии, которая поставляется в составе.NET Framework 3.0 (4.0), все определения тегов XAML реализованы в виде типов CLR. Поэтому все, что можно сделать с помощью разметки, можно написать и в виде компилируемой программы.
Дата добавления: 2015-08-13; просмотров: 108 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Разделение труда дизайнера и разработчика | | | Ключевые термины |