何时使用{x:Type...}作为Style的TargetType?

31

这两者有什么区别:

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

并且:

<Style TargetType="Border">

何时以及为什么需要使用{x:Type ...}


3
+1 好问题。我猜第二个应该是一种新的、更好的符号表示法。 - McGarnagle
3
类似的旧Stack Overflow问题 - https://dev59.com/CHNA5IYBdhLWcg3wHqCB#9128422 和 https://dev59.com/QFXTa4cB1Zd3GeqP3Z9O#9127377 - akjoshi
这个回答解决了你的问题吗?TargetType="controlType"和TargetType="{x:Type controlType}"之间的区别 - StayOnTarget
这个回答解决了你的问题吗?TargetType="{x:Type Button}"和TargetType="Button"有什么区别? - StayOnTarget
5个回答

19
没有效果上的区别;在两种情况下,TargetType属性都将被设置为typeof(Border)
第一个版本{x:Type Border}在WPF的第一个版本中是必需的,因为编译器没有使用类将字符串转换为Type对象,您需要指定类来完成这项工作。
第二个版本是在Silverlight中引入的,如果我没记错的话,很快就被WPF编译器采用了。
编辑
我对类的假设是错误的;这是由实现的:
来自文档支持类型名称作为字符串的类型属性 WPF 支持一些技术,使得可以在不需要使用 x:Type 标记扩展的情况下指定某些 Type 类型的属性的值。相反,可以将值指定为命名该类型的字符串。其中 ControlTemplate.TargetType 和 Style.TargetType 是这种情况的示例。这种行为的支持不是通过类型转换器或标记扩展来提供的,而是通过 FrameworkElementFactory 实现的延迟行为。
Silverlight 支持类似的约定。实际上,Silverlight 目前不支持 {x:Type} 在其 XAML 语言支持中,并且不接受 {x:Type} 的用法,除了一些旨在支持 WPF-Silverlight XAML 迁移的情况之外。因此,类型名称作为字符串的行为内置于所有 Silverlight 原生属性评估中,其中 Type 是值。

6
尽管在给定的示例中没有区别,但实际上,在涉及自定义类型时,x:TypeTypeName-as-String之间存在差异。根据我的经验 - x:Type考虑程序集的强名称或版本(其中类型驻留),而TypeName-as-String则不考虑。我在我的博客中解释了我的情况和其他细节。此外,WPF推断类型的方式也有所不同。对于x:Type,使用TypeExtension,而对于TypeName-as-String,使用FrameworkElementFactory(如Erno所述)。请参阅:指定RelativeSourceBinding中x:Type的AncestorType的重要性

2
将此属性(TargetType)设置为Border而不使用x:Key分配样式,允许将样式应用于所有Border元素。但是,当您将x:Key设置为{x:Type Border}时,这意味着如果您给Style赋值一个除{x:Type Border}之外的任何其他值,Style将不会自动应用于所有Border元素。相反,您需要显式地将样式应用于Border元素。

1

两者完全相同。在任何一种情况下,您的样式都将仅适用于Border


“Both are exactly same”:它们很相似,就像string.Emptynew string('x', 0)一样相似:它们产生相同的有效结果,但是通过不同的方式实现。 - mins

0

如果您正在使用XAML 2009,则可以将x:Key指定为元素,以明确支持键为对象类型的字典,而无需中间的标记扩展。请参见本主题中的“XAML 2009”部分。备注部分的其余部分特别适用于XAML 2006实现。

x:Key的属性值可以是XamlName语法中定义的任何字符串,也可以是通过标记扩展评估的对象。有关WPF的示例,请参见“WPF使用说明”。

父元素的子元素,它是IDictionary实现,通常必须包括一个x:Key属性,该属性指定该字典中的唯一键值。框架可能会实现别名键属性以替代特定类型上的x:Key;定义此类属性的类型应带有DictionaryKeyPropertyAttribute。

指定x:Key的代码等效于用于基础IDictionary的键。例如,在WPF中为资源应用的x:Key相当于ResourceDictionary.Add的key参数的值,当您将资源添加到WPF ResourceDictionary时。

x:Type标记扩展具有类似于C#中typeof()运算符或Microsoft Visual Basic中GetType运算符的功能。

x:Type标记扩展为接受Type类型属性的属性提供了一种从字符串转换的行为。输入是一个XAML类型。输入XAML类型和输出CLR类型之间的关系是,在查找必要的XamlType时,输出类型是输入XamlType的UnderlyingType,基于XAML模式上下文和上下文提供的IXamlTypeResolver服务。

在.NET Framework XAML Services中,此标记扩展的处理由TypeExtension类定义。

在特定的框架实现中,一些以Type作为值的属性可以直接接受类型名称(类型名称的字符串值)。但是,实现此行为是一个复杂的场景。有关示例,请参见以下“WPF使用说明”部分。

属性语法是与此标记扩展一起使用的最常见语法。在x:Type标识符字符串后提供的字符串标记被分配为底层TypeExtension扩展类的TypeName值。在.NET Framework XAML Services的默认XAML模式上下文下,该属性的值是所需类型的名称,或包含该名称前缀的非默认XAML命名空间映射。

x:Type标记扩展可以在对象元素语法中使用。在这种情况下,指定TypeName属性的值是必需的,以正确初始化扩展。

x:Type 标记扩展也可以用作冗长属性;但是这种用法并不典型:


4
如果你复制一份测试,应该提供链接和/或给予原作者信用。 - Emond
检测到Ctrl+C,Ctrl+V :) - Ruslan Veselov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接