TypeConverters и XAML

Этот раздел посвящен цели преобразования типов из строк — одной из основных функций языка XAML. В платформа .NET Framework TypeConverter класс служит определенной целью в рамках реализации управляемого пользовательского класса, который можно использовать в качестве значения свойства в использовании атрибута XAML. Если вы пишете пользовательский класс и хотите, чтобы экземпляры класса могли использоваться в качестве значений атрибутов наборной таблицы XAML, может потребоваться применить к TypeConverterAttribute классу, написать пользовательский TypeConverter класс или оба.

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

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

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

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

Использование поведения преобразования существующего типа в XAML

В зависимости от уровня понимания концепций XAML, вы, возможно, уже используете преобразование типа в простом приложении XAML, не реализуя его. Например, WPF определяет буквально сотни свойств, которые принимают значение типа Point. Это Point значение, описывающее координату в двухмерном пространстве координат, и она действительно имеет два важных свойства: X и Y. При указании точки в XAML вы указываете ее как строку с разделителем (обычно запятой) между XY предоставленными значениями. Например: <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"/>.

Даже этот простой Point тип и его простое использование в XAML включают преобразователь типов. В этом случае это класс PointConverter.

Преобразователь типов, Point определенный на уровне класса, упрощает использование разметки всех используемых свойств Point. Без преобразователя типов для создания примера, показанного выше, требуется гораздо больше разметки.

<LinearGradientBrush>
  <LinearGradientBrush.StartPoint>
    <Point X="0" Y="0"/>
  </LinearGradientBrush.StartPoint>
  <LinearGradientBrush.EndPoint>
    <Point X="1" Y="1"/>
  </LinearGradientBrush.EndPoint>
</LinearGradientBrush>

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

Существующие преобразователи типов, как правило, можно обнаружить в WPF и платформа .NET Framework типах, проверка класс (или свойство) для присутствия примененногоTypeConverterAttribute. Этот атрибут содержит имя класса, поддерживающего преобразование для данного типа, как для XAML, так потенциально и для других целей.

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

Расширения разметки и преобразователи типов играют ортогональные роли в терминах поведения обработчика XAML и сценариев, к которым они применяются. Хотя для расширения разметки контекст доступен, поведение преобразования типов свойств, когда расширение разметки предоставляет значение, обычно не включается в реализацию расширения разметки. Другими словами, даже если расширение разметки возвращает текстовую строку в качестве выходных данных ProvideValue, преобразование типа для этой строки относительно конкретного свойства или типа значения свойства не применяется. Обычно целью расширения разметки является обработка строки и возврат объекта без использования какого бы то ни было преобразователя типов.

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

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

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

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

TypeConverter

В приведенном Point ранее примере класс PointConverter был упоминание. Для реализаций XAML все преобразователи типов, используемые для целей XAML, являются классами, производными от базового класса TypeConverter. Класс TypeConverter существовал в версиях платформа .NET Framework, которые предшествовали существованию XAML; одно из его исходных использования — обеспечить преобразование строк для диалогов свойств в визуальных конструкторах. Для XAML роль TypeConverter расширяется, чтобы включить базовый класс для преобразования строк и из строки, которые позволяют анализировать значение строкового атрибута и, возможно, обрабатывать значение времени выполнения определенного свойства объекта обратно в строку для сериализации в качестве атрибута.

TypeConverter определяет четыре члена, которые относятся к преобразованию в строки и из строк для целей обработки XAML:

Из них наиболее важным является метод ConvertFrom. Этот метод преобразует входную строку к требуемому типу объекта. Строго говоря, ConvertFrom метод может быть реализован для преобразования гораздо более широкого диапазона типов в предполагаемый тип назначения преобразователя, и таким образом служит целям, которые выходят за рамки XAML, таких как поддержка преобразований во время выполнения, но для целей XAML это только путь кода, который может обрабатывать String входные данные, которые имеют значение.

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

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

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

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

Пример того, что учет языка и региональных параметров может быть важен: некоторые языки и региональные параметры используют запятую в качестве десятичного разделителя. Это входит в противоречие с поведением многих преобразователей типов WPF XAML, которые используют запятую в качестве разделителя (исторически в обычной форме X,Y или в списках, разделенных запятыми). Даже передача языка и региональных параметров в окружающий XAML (установка параметра Language или xml:lang в значение sl-SI, как пример языка и региональных параметров, использующих запятую в качестве десятичного разделителя) не решает проблемы.

Реализация ConvertFrom

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

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

Примечание.

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

Реализация ConvertTo

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

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

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

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

Реализация CanConvertTo

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

Реализация CanConvertFrom

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

Применение TypeConverterAttribute

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

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

См. также