Подтвердить что ты не робот

Когда использовать {x: Тип...}?

В чем разница между:

<Style TargetType="{x:Type Border}">

и:

<Style TargetType="Border">

Когда и зачем мне использовать {x:Type …}?

4b9b3361

Ответ 1

Нет никакой разницы в эффекте; в обоих случаях свойство TargetType будет установлено на typeof(Border)

Первая версия {x:Type Border} была необходима в первой версии WPF, потому что компилятор не использовал класс TypeConverter для преобразования строки в объект Type, и вам нужно было указать класс TypeExtension, чтобы сделать это для вы.

Вторая версия была введена, если я правильно помню, с Silverlight и быстро нашел свой путь к компилятору WPF.

ИЗМЕНИТЬ

Мое предположение в классе TypeConverter было неправильным; это реализовано с помощью FrameworkElementFactory:

Из документация:

Свойства типа, которые поддерживают Typename-as-String

WPF поддерживает методы, которые позволяют указать значение некоторых свойства типа Тип без требования x: Расширение разметки типа Применение. Вместо этого вы можете указать значение как строку, которая называет тип. Примерами этого являются ControlTemplate.TargetType и Style.TargetType. Поддержка такого поведения не обеспечивается либо преобразователи типов, либо расширения разметки. Вместо этого это отложенное поведение, реализованное через FrameworkElementFactory.

Silverlight поддерживает аналогичное соглашение. Фактически, Silverlight делает в настоящее время не поддерживает {x: Type} в своей поддержке языка XAML и делает не принимайте {x: Тип} использование за пределами нескольких обстоятельств, которые предназначенный для поддержки миграции WPF-Silverlight XAML. Следовательно поведение typename-as-string встроено во все родные Silverlight оценка свойства, где Type является значением.

Ответ 2

Хотя в данном примере это не имеет никакого значения, но на самом деле существует разница между x:Type и TypeName-as-String.

Недавно я столкнулся с ситуацией, которая показывает, что x:Type отличается от TypeName-as-String, когда речь заходит о настраиваемых типах. По моему опыту -

x:Type рассматривает сильное имя или версию сборки (в каком типе находится), но не TypeName-as-String.

Я рассказал о своем сценарии и других деталях в моем блоге здесь -

Значение указания AncestorType с x: Введите RelativeSourceBinding

Кроме того, существует также разница в том, как WPF вводит тип. Для x:Type TypeExtension используется, тогда как для TypeName-as-String FrameworkElementFactory используется (как упоминал Эрно).

Ответ 3

Установка этого свойства (TargetType) в Border без назначения стиля с помощью x:Key позволяет применять стиль к всем элементам Border. Но когда вы устанавливаете значение x:Key в {x:Type Border}, это означает, что если вы укажете значение Style a x:Key всего, кроме {x:Type Border}, то Style не будет применяться ко всем элементам Border автоматически. Вместо этого вам нужно явно применить стиль к элементам Border.

Ответ 4

Оба одинаковы. В любом из случаев ваш стиль будет применяться только к Border.

Ответ 5

Если вы используете XAML 2009, x: Key может быть указан как элемент, чтобы явно поддерживать словари, на которые ссылаются типы объектов, отличные от строк, без промежуточного расширения разметки. См. Раздел "XAML 2009" в этом разделе. Остальная часть раздела "Замечания" относится конкретно к реализации XAML 2006.

Значение атрибута x: Key может быть любой строкой, определенной в грамматике XamlName, или может быть объектом, оцененным через расширение разметки. См. "Примечания к использованию WPF" для примера из WPF.

Элементы дочернего элемента родительского элемента, который является реализацией IDictionary, обычно должны включать атрибут x: Key, который указывает уникальное значение ключа в этом словаре. Структуры могут реализовывать свойства псевдонимов ключевых слов для замены x: Key на определенные типы; типы, которые определяют такие свойства, должны быть отнесены к DictionaryKeyPropertyAttribute.

Кодовый эквивалент указания x: Key - это ключ, который используется для базового IDictionary. Например, x: Ключ, который применяется в разметке для ресурса в WPF, эквивалентен значению ключевого параметра ResourceDictionary.Add, когда вы добавляете ресурс в WPF ResourceDictionary в код. Расширение разметки x: Type имеет аналогичную функцию с оператором typeof() в С# или оператором GetType в Microsoft Visual Basic.

Расширение разметки x: Type предоставляет поведение преобразования строк для свойств, которые принимают тип Type. Вход представляет собой тип XAML. Связь между входным типом XAML и выходным CLR Type заключается в том, что тип вывода - это тип UnderlyingType входного XamlType, после поиска необходимого XamlType на основе контекста схемы XAML и услуги IXamlTypeResolver, предоставляемой контекстом.

В .NET Framework XAML Services обработка этого расширения разметки определяется классом TypeExtension.

В конкретных реализациях Framework некоторые свойства, которые принимают тип как значение, могут напрямую принимать имя типа (строковое значение типа Name). Однако реализация этого поведения является сложным сценарием. Например, см. Раздел "Примечания к использованию WPF", который следует далее.

Синтаксис атрибутов - наиболее распространенный синтаксис, используемый с этим расширением разметки. Символ строки, предоставленный после строки идентификатора типа x: Type, присваивается как значение TypeName базового класса расширения TypeExtension. В контексте контекста XAML по умолчанию для .NET Framework XAML Services, который основан на типах CLR, значение этого атрибута является либо именем желаемого типа, либо содержит это имя, которому предшествует префикс для отображения пространства имен XAML, отличного от значения по умолчанию.

Расширение разметки x: Type можно использовать в синтаксисе элемента объекта. В этом случае для правильной инициализации расширения необходимо указать значение свойства TypeName.

Расширение разметки x: Type также может использоваться как подробный атрибут; однако это использование не является типичным: