Пространства имен XAML и сопоставление пространств имен для WPF XAML

В этом разделе обосновывается наличие и рассматриваются цели сопоставления двух пространств имен XAML, обычно содержащихся в корневом теге файла WPF XAML. Также описываются способы создания аналогичных сопоставлений для использования элементов, заданных в коде и/или в отдельных сборках.

Общие сведения о пространстве имен XAML

Пространство имен XAML — это расширение концепции пространства имен XML. При указании пространства имен XAML используется синтаксис пространства имен XML: соблюдается принцип использования универсальных кодов ресурсов (URI) в качестве идентификаторов пространств имен, использование префиксов, позволяющих указать несколько пространств имен с общим исходным кодом разметки и т. п. Основное нововведение в определении пространства имен XML, используемом в XAML, заключается в том, что пространство имен XAML неявно задает область уникальности используемой разметки и при этом влияет на возможное дополнение сущностей разметки определенными пространствами имен CLR и указанными в них сборками. Последний фактор обусловлен в том числе природой контекста схемы XAML. Впрочем, в отношении взаимодействия WPF с пространствами имен XAML можно рассматривать пространства имен XAML с учетом пространства имен XAML по умолчанию, пространства имен языка XAML и любых других пространств имен XAML, напрямую сопоставленных в разметке XAML с дополняющими их пространствами имен CLR и указанными в них сборками.

WPF и объявления пространства имен XAML

В объявлении пространства имен в корневом теге многих XAML-файлов, как правило, содержатся два объявления пространства имен XML. Первое объявление задает сопоставление для общего пространства имен клиента WPF и платформы XAML как для пространства имен по умолчанию.

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

Второе объявление сопоставляет отдельное пространство имен XAML, сопоставляя его (обычно) с префиксом x:.

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Связь между этими объявлениями состоит в том, что сопоставление префикса x: поддерживает встроенные функции, которые являются частью определения языка XAML и WPF является реализацией, которая использует XAML в качестве языка и определяет словарь объектов для XAML. Так как использование словаря WPF более распространено, чем использование встроенных функций XAML, словарь WPF сопоставляется по умолчанию.

Поддержка соглашения префикса x: для сопоставления встроенных функций языка XAML также используется в шаблонах проектов, образцах кода и документации по возможностям языка в этом SDK. Пространство имен XAML определяет многие часто используемые функциональные возможности, которые необходимы даже для основных приложений WPF. Например, чтобы присоединить какой-либо код программной части к XAML-файлу через разделяемый класс, необходимо именовать класс как атрибут x:Class в корневом элементе соответствующего XAML-файла. Или же любой элемент, определенный на странице XAML, к которой необходимо получить доступ в качестве ключевого ресурса, должен иметь заданный атрибут x:Key. Дополнительные сведения об этих и других аспектах XAML см. в разделах XAML в WPF или Подробное описание синтаксиса XAML.

Сопоставление пользовательских классов и сборок

Вы можете сопоставить пространства имен XML со сборками, используя серию токенов в объявлении префиксов xmlns аналогично тому, как стандартные пространства имен WPF и встроенных функций XAML сопоставляются с префиксами.

Синтаксис допускает перечисленные ниже возможные именованные токены и значения.

clr-namespace: Пространство имен CLR объявлено внутри сборки, которая содержит открытые типы, предоставленные как элементы.

assembly= Сборка, которая содержит все пространство имен CLR, на которое указывает ссылка, или его часть. Это значение обычно содержит только имя сборки, но не путь к ней, и не включает расширение имени файла (например, EXE или DLL). Путь к этой сборке должен быть задан в качестве ссылки проекта в файле проекта, который содержит код XAML, который следует сопоставить. Чтобы включить управление версиями и подписи строгих имен, значение assembly может быть строкой, которая определяется классом AssemblyName, а не простым именем строки.

Обратите внимание, что токен clr-namespace отделяется от значения двоеточием (:), тогда как токен assembly отделяется от значения знаком равенства (=). Эти два токена разделяются точкой с запятой. Кроме того, не включайте пробел в объявление.

Простой пример пользовательского сопоставления

В следующем примере кода определяется пользовательский класс.

namespace SDKSample {  
    public class ExampleClass : ContentControl {  
        public ExampleClass() {  
        ...  
        }  
    }  
}  
Namespace SDKSample  
    Public Class ExampleClass  
        Inherits ContentControl  
         ...  
        Public Sub New()  
        End Sub  
    End Class  
End Namespace  

Затем пользовательский класс компилируется в библиотеку, которая согласно параметрам проекта (не показано) имеет имя SDKSampleLibrary.

Для ссылки на этот пользовательский класс также следует включить его в качестве ссылки на текущий проект, что обычно делается с помощью пользовательского интерфейса обозревателя решений в Visual Studio.

Теперь, когда есть библиотека с классом и ссылка на него в параметрах проектах, можно добавить следующее сопоставление префикса как часть корневого элемента в XAML.

xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary"

Чтобы собрать это все вместе, используется приведенный ниже код XAML, в который включено пользовательское сопоставление с обычным сопоставлением и сопоставлением x: в корневом теге. Затем используется ссылка с префиксом для создания экземпляра ExampleClass в этом пользовательском интерфейсе.

<Page x:Class="WPFApplication1.MainPage"  
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
    xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary">  
  ...  
  <custom:ExampleClass/>  
...  
</Page>  

Сопоставление с текущими сборками

Можно опустить assembly, если указанное пространство имен clr-namespace определяется в этой же сборке в качестве кода приложения, который ссылается на пользовательские классы. Аналогичный способ для этого случая ― указание assembly= без строкового токена после знака равенства.

Пользовательские классы нельзя использовать в качестве корневого элемента страницы, если они определены в той же сборке. Разделяемые классы не требуют сопоставления; должны быть сопоставлены только классы, которые не являются разделяемыми классами страницы в приложении, если планируется ссылка на них как на элементы в XAML.

Сопоставление пространств имен CLR с пространствами имен XML в сборке

WPF определяет атрибут CLR, который обрабатывается процессорами XAML для сопоставления нескольких пространств имен CLR с одним пространством имен XAML. Этот атрибут XmlnsDefinitionAttribute помещается на уровне сборки в исходном коде, который создает сборку. Исходный код сборки WPF использует этот атрибут для сопоставления различных общих пространств имен, например System.Windows и System.Windows.Controls, пространству имен http://schemas.microsoft.com/winfx/2006/xaml/presentation.

XmlnsDefinitionAttribute принимает два параметра: имя пространства имен XML/XAML и имя пространства имен CLR. Может существовать несколько XmlnsDefinitionAttribute для сопоставления нескольких пространств имен CLR одному и тому же пространству имен XML. После сопоставления на члены этих пространств имен при желании можно ссылаться без указания полного имени, предоставляя соответствующий оператор using на странице с выделенным кодом разделяемого класса. Дополнительные сведения см. в статье XmlnsDefinitionAttribute.

Пространства имен конструктора и другие префиксы из шаблонов XAML

При работе в средах разработки или со средствами разработки для WPF XAML можно заметить, что в разметке XAML определены и другие пространства имен и префиксы XAML.

Конструктор WPF для Visual Studio использует пространство имен конструктора, которое, как правило, сопоставляется префиксу d:. В новейших шаблонах проектов для WPF это пространство имен XAML иногда заранее сопоставляется так, чтобы обеспечить поддержку переноса кода XAML между конструктором WPF для Visual Studio и другими средами разработки. Это пространство имен XAML для разработки используется с целью сохранения состояния среды разработки при переносе пользовательского интерфейса, созданного на основе XAML, из одного средства разработки в другое. Оно также используется в таких функциях как d:IsDataSource, позволяющих использовать источники данных среды выполнения в конструкторе.

Среди сопоставленных префиксов также встречается mc:. Префикс mc: используется для обеспечения совместимости разметки. С его помощью можно обеспечить шаблон совместимости не только для языка XAML. Функции обеспечения совместимости разметки в некоторой степени можно использовать для обмена кодом XAML между различными платформами, взаимодействия между различными схемами XAML, обеспечения совместимости для ограниченных режимов в конструкторах и т. п. Дополнительные сведения о принципах обеспечения совместимости разметки и их применении к WPF см. в разделе Совместимость разметки (mc:) языковые компоненты.

WPF и загрузка сборок

Контекст схемы XAML для WPF тесно связан с моделью приложений WPF, которая, в свою очередь, использует определенное в среде CLR понятие AppDomain. В приведенной ниже последовательности показано, как контекст схемы XAML интерпретирует либо порядок загрузки сборок, либо порядок поиска типов во время выполнения или во время разработки, основываясь на использовании AppDomain в WPF и других факторах.

  1. Здесь выполняется перебор объектов AppDomain с целью поиска уже загруженной сборки, соответствующей всем аспектам имени, начиная с последней загруженной сборки.

  2. Если имя полное, вызовите Assembly.Load(String) для полного имени.

  3. Если сборке, из которой была загружена разметка, соответствует сочетание "короткое имя + токен открытого ключа полного имени", возвратите эту сборку.

  4. Используйте короткое имя + токен открытого ключа, чтобы вызвать Assembly.Load(String).

  5. Если имя неполное, вызовите Assembly.LoadWithPartialName.

Свободный XAML не использует шаг 3, так как нет сборки, из которой выполнялась загрузка.

Скомпилированный XAML для WPF (сформированный с помощью XamlBuildTask) не использует уже загруженные сборки из AppDomain (шаг 1). Кроме того, имя из выходных данных XamlBuildTask не должно быть неполным, поэтому шаг 5 не применяется.

Скомпилированный BAML (сформированный с помощью PresentationBuildTask) использует все шаги, хотя BAML также не должен содержать неполные имена сборок.

См. также