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

Преобразователи типов предоставляют логику для средства записи объекта, преобразующую строку в разметке XAML в конкретные объекты в графе объектов. В службах XAML .NET преобразователь типов должен быть классом, производным от TypeConverter . Некоторые преобразователи также поддерживают путь сохранения XAML и могут использоваться для сериализации объекта в виде строки в разметке сериализации. В этом разделе описывается, как и когда вызываются преобразователи типов в XAML, а также представлены рекомендации по реализации переопределений методов класса TypeConverter.

Понятия преобразования типов

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

XAML и строковые значения

При установке значения атрибута в файле XAML начальный тип этого значения — это строка в общем смысле и значение строкового атрибута в контексте XML. Даже другие примитивные типы, такие как Double , изначально являются строками для обработчика XAML.

В большинстве случаев XAML-обработчику требуется два компонента для обработки значения атрибута. Первый из них — это тип значения свойства, которое должно быть задано. Любую строку, которая определяет значение атрибута и обрабатывается в XAML, в конечном счете необходимо преобразовать или разрешить в значение этого типа. Если значение — примитивный тип, понятный средству синтаксического анализа XAML (например, числовое значение), выполняется попытка прямого преобразования строки. Если значение атрибута ссылается на перечисление, предоставленная строка проверяется на совпадение имени с именем константы в этом перечислении. Если значение не является примитивом, понятным синтаксическим анализатором, или именем константы из перечисления, соответствующий тип должен иметь возможность предоставить значение или ссылку, основанную на преобразованной строке.

Примечание

Директивы языка XAML не используют преобразователи типов.

Преобразователи типов и расширения разметки

Процессор XAML должен обработать расширения разметки, прежде чем он проверит тип свойства и другие аспекты. Например, если устанавливаемое как атрибут свойство обычно использует преобразования типов, однако в конкретном случае задается расширение разметки, сначала обрабатывается расширение разметки. Одна из распространенных ситуаций, где необходимо расширение разметки — указание ссылки на объект, который уже существует. Для этого сценария преобразователь типов без состояния может создать только новый экземпляр, что может быть нежелательно. Дополнительные сведения о расширениях разметки см. в разделе Markup Extensions for XAML Overview.

Собственные преобразователи типа

в реализациях служб Windows Presentation Foundation (WPF) и .net XAML существуют определенные типы CLR, которые имеют собственную обработку преобразования типов. Однако эти типы CLR не считаются примитивами. Пример такого типа — DateTime. Одна из причин этого — работа архитектуры платформы .NET Framework: тип DateTime определяется в mscorlib, в основной библиотеке .NET. DateTime атрибут не разрешен с атрибутом, поступающим из другой сборки, которая вводит зависимость ( TypeConverterAttribute из системы). Поэтому стандартный механизм обнаружения преобразователя типов с помощью атрибутов не поддерживается. Вместо этого средство синтаксического анализа XAML использует список типов, требующих собственный обработки. Эти типы обрабатываются как настоящие примитивы. В случае DateTimeпри обработке вызывается Parse.

Реализация преобразователя типов

В следующих разделах рассматриваются API-интерфейс класса TypeConverter .

TypeConverter

В разделе службы XAML .NET все преобразователи типов, используемые для целей XAML, являются классами, производными от базового класса TypeConverter . Класс TypeConverter существовал в версиях .NET Framework до появления XAML. Один исходный сценарии TypeConverter использовался для преобразование строк в редакторах свойств визуальных конструкторов.

Для XAML роль TypeConverter расширяется. В XAML TypeConverter — это базовый класс для поддержки определенных преобразований в строку и из строки. Преобразование из строки позволяет выполнить анализ значения строкового атрибута из XAML. Преобразование в строку позволяет преобразовать значение определенного свойства объекта во время выполнения в атрибут в XAML для сериализации.

ВTypeConverter определены четыре элемента, относящихся к преобразованию в строку и из строки для обработки XAML:

Наиболее важный из этих элементов — это метод ConvertFrom, который преобразует входную строку в требуемый тип объекта. Метод ConvertFrom можно реализовать для преобразования более широкого диапазона типов в требуемый конечный тип преобразователя. Таким образом его можно использовать в целях, выходящих за пределы языка XAML, например для поддержки преобразований во время выполнения. Однако для XAML важен только путь кода, который может обрабатывать входные данные String .

Второй важный метод — ConvertTo . Если приложение преобразуется в представление разметки (например, если оно сохранено в XAML как файл), то ConvertTo в более крупном сценарии модуля записи текста XAML для создания представления разметки. В этом случае важный путь кода XAML — передача вызывающим объектом destinationType из String.

CanConvertTo и CanConvertFrom — это вспомогательные методы, используемые, когда служба запрашивает возможности реализации TypeConverter . Вам необходимо реализовать эти методы для возврата true для определенных типов. Они аналогичны методам преобразования для поддержки вашего преобразователя. В целях XAML обычно это означает тип String .

Сведения о языке и преобразователи типов для XAML

Каждая реализация TypeConverter может однозначно интерпретировать допустимую строку для преобразования, а также может использовать или игнорировать описание типа, переданного в качестве параметров. Важный аспект для региональных параметров и преобразования типов XAML: хотя использование локализуемых строк в качестве значений атрибутов поддерживается в XAML, невозможно применять эти локализуемые строки в качестве входных данных преобразователя типов с определенными требованиями для региональных параметров. Это ограничение вызвано тем, что преобразователи типов для значений атрибутов XAML обязательно используют фиксированное поведение обработки XAML, для чего применяются региональные параметры en-US . Дополнительные сведения о причинах этого ограничения см. в статье спецификация языка XAML ( [ MS-XAML ] ), а также Обзор глобализации и локализации WPF.

Вот пример проблемы с языком и региональными параметрами: в некоторых языках в качестве десятичного разделителя для чисел в виде строки вместо точки используется запятая. Это противоречит поведению многих существующих преобразователей типов, которые используют запятую в качестве разделителя. Передача языка через xml:lang в XAML не решает проблему.

Реализация ConvertFrom

Для использования в качестве реализации TypeConverter , поддерживающей XAML, метод ConvertFrom данного преобразователя должен принимать строку как параметр value . Если строка представлена в допустимом формате и может быть преобразована реализацией TypeConverter , возвращаемый объект должен поддерживать приведение к типу, ожидаемому свойством. В противном случае реализация ConvertFrom должна возвращать null.

Каждая реализация TypeConverter может однозначно интерпретировать допустимую строку для преобразования, а также может использовать или игнорировать описание типа или контекст языка, переданного в качестве параметров. Однако обработка XAML в WPF может не передавать значения в контекст описания типа во всех случаях, а также может не передавать язык на основе xml:lang.

Примечание

Не используйте фигурные скобки ( {} ), в частности открывающую фигурную скобку ({), как элемент формата строки. Эти символы зарезервированы как вход и выход для последовательности расширения разметки.

Может возникнуть исключение, если преобразователь типов должен иметь доступ к службе XAML из модуля записи объектов служб XAML .NET, но GetService вызов, выполняемый в контексте, не возвращает эту службу.

Реализация ConvertTo

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

Для использования в качестве реализации TypeConverter , поддерживающей XAML, метод ConvertTo данного преобразователя должен принимать экземпляр поддерживаемого типа (или значение) как параметр value . Если тип параметра destinationType — тип String, возвращаемый объект должен иметь возможность приведения к String. Возвращаемая строка должна представлять сериализованное значение value. В идеальном случае выбранный формат сериализации должен позволять создавать то же значение, как и при передаче строки реализации ConvertFrom того же преобразователя без значительной потери информации.

Если значение не может быть сериализовано или преобразователь не поддерживает сериализацию, реализация ConvertTo должна возвращать null и может вызывать исключение. Однако при создании исключений, следует сообщать о невозможности использовать это преобразование в вашей реализации CanConvertTo , поэтому рекомендуется проверять с помощью CanConvertTo , чтобы предотвратить исключения.

Если параметр destinationType не относится к типу String, можно выбрать собственную обработку преобразователя. Как правило, вы возвращаетесь к базовой обработке реализации, которая с помощью ConvertTo вызывает определенное исключение.

Может возникнуть исключение, если преобразователь типов должен иметь доступ к службе XAML из модуля записи объектов служб XAML .NET, но GetService вызов, выполняемый в контексте, не возвращает эту службу.

Реализация CanConvertFrom

Ваша реализация CanConvertFrom должна возвращать true для sourceType типа String , а в противном случае обращаться к базовой реализации. Не вызывайте исключения из CanConvertFrom.

Реализация CanConvertTo

Ваша реализация CanConvertTo должна возвращать true для destinationType типа String, а в противном случае обращаться к базовой реализации. Не вызывайте исключения из CanConvertTo.

Применение TypeConverterAttribute

Чтобы пользовательский преобразователь типов использовался в качестве преобразователя действующего типа для пользовательского класса в службах .NET XAML, необходимо применить TypeConverterAttribute к определению класса. Имя ConverterTypeName , указываемое в атрибуте, должно быть именем типа пользовательского преобразователя типов. Если этот атрибут применяется, обработчик XAML может передать строки и вернуть экземпляры объекта, когда он обрабатывает значения, в которых тип свойства применяет тип пользовательского класса.

Вы также можете предоставить преобразователь типов для отдельных свойств. Вместо применения TypeConverterAttribute к определению класса примените его к определению свойства (основное определение, а не к get / set реализации внутри него). Тип свойства должен соответствовать типу, который обрабатывается пользовательским преобразователем типов. Если этот атрибут применяется, обработчик XAML может обработать входные строки и вернуть экземпляры объекта при работе со значениями этого свойства. использование преобразователя типов для каждого свойства полезно, если вы решили использовать тип свойства из Microsoft платформа .NET Framework или из другой библиотеки, где нельзя управлять определением класса и применять его TypeConverterAttribute .

Чтобы реализовать поведение преобразования типов для пользовательского присоединенного члена, примените TypeConverterAttribute к методу доступа Get шаблона реализации присоединенного члена.

Доступ к контексту поставщика службы из реализации расширения разметки

Доступные службы одинаковы для всех преобразователей значений. Разница заключается в том, как преобразователь значения получает контекст службы. Доступ к службам и предоставляемые службы описаны в разделе Type Converters and Markup Extensions for XAML.

Преобразователи значений в потоке узлов XAML

При работе с потоком узлов XAML действие преобразователя типов еще не выполнено (или результат не достигнут). В пути загрузки строка атрибута, которой со временем потребуется преобразовать для загрузки, остается текстовым значением в пределах начального и конечного элемента. Преобразователь типов, который потребуется для этой операции, можно определить с помощью свойства XamlMember.TypeConverter . Однако для получения допустимого значения из XamlMember.TypeConverter необходим контекст схемы XAML, который может получить доступ к такой информации через базовый член, или тип объектного значения, используемого этим членом. Для вызова преобразования типов также необходим контекст схемы XAML, так как для этого требуется сопоставление типов и создание экземпляра преобразователя.

См. также