TypeConverters 和 XAML

更新:2007 年 11 月

TypeConverter 类作为托管自定义实现的一部分具有特定的用途,该托管自定义实现在可扩展应用程序标记语言 (XAML) 属性用法中可用作属性值。如果编写一个自定义类,并需要将类的实例用作可扩展应用程序标记语言 (XAML) 可设置的属性值,则可能需要对类应用 TypeConverterAttribute,或者编写一个自定义 TypeConverter 类,或者二者都需要。

本主题包括下列各节。

  • XAML 和字符串值
  • 实现类型转换器
  • 应用 TypeConverterAttribute
  • 相关主题

XAML 和字符串值

当在 XAML 中设置属性值时,该值的初始类型为 String。尽管由于存在内置类型,到其他非字符串基元值的转换或者从枚举的已命名值的转换相对来说更为直观,甚至于如 Double 这样的其他基元对于 XAML 处理器最初也为字符串。

XAML 处理器需要两条信息以处理属性值。第一条信息是要设置的属性的值类型。定义属性值和在 XAML 中处理的任何字符串都必须最终转换为或解析为该类型的值。如果该值是一个基元,则将尝试直接转换该字符串。如果该值是一个枚举,则使用字符串检查该枚举中的名称匹配。如果该值既不是一个基元也不是一个枚举,则所涉及的类型必须能够基于转换的字符串提供该类的实例或值。

标记扩展是一个特例。标记扩展用法必须在检查属性类型和其他注意事项之前由 XAML 处理器进行处理。通常,标记扩展的用途是处理字符串并返回一个对象。如果返回的对象是属性的类型匹配项,则标记扩展以避免任何类型转换在标记扩展实现代码以外发生的方式为属性提供一个值。一种常见的情况是需要标记扩展来对已经存在的对象进行引用(在最佳情况下,无状态类型转换器仅能生成一个新实例,而且该实例可能并不是所需要的)。有关标记扩展的更多信息,请参见标记扩展和 XAML

TypeConverter

如果该值既不是基元类型也不是枚举,且不存在标记扩展用法,则在处理 XAML 时,必须存在一些将 String 转换为适当值或新实例的方式。这就是 TypeConverter 实现的角色。TypeConverter 出于 XAML 处理目的定义四个与转换为字符串和从字符串转换相关的成员:

其中,最重要的方法是 ConvertFrom。此方法将输入的字符串转换为必需的对象类型。

下一个最重要的方法是 ConvertTo。如果 WPF 应用程序转换为标记表示形式(例如,如果它保存到 XAML),则 ConvertTo 将负责生成标记表示形式。

CanConvertToCanConvertFrom 是当服务查询 TypeConverter 实现的功能时使用的支持方法。必须实现这些方法以便针对某些情况返回 true,尤其是对于 String 类型。

实现类型转换器

实现 ConvertFrom

若要将该转换器的 ConvertFrom 方法用作支持 XAML 的 TypeConverter 实现,该方法必须将字符串作为 value 参数接受。如果该字符串的格式有效,而且可以由 TypeConverter 实现进行转换,则返回的对象必须支持强制转换为该属性所预期的类型。否则,ConvertFrom 实现必须返回 null。

每个 TypeConverter 实现都可以有其自己对组成有效转换字符串的内容的解释,还可以使用或忽略作为参数传递的类型描述或区域性上下文。但是,WPF XAML 处理可能不会在任何情况下都传递值到类型描述上下文,而且还可能不基于 xml-lang 传递区域性信息。

说明:

请勿使用大括号字符,尤其是 {,其原因是它有可能作为您字符串格式的一个元素。这些字符保留为标记扩展序列的入口和出口。

实现 ConvertTo

ConvertTo 可潜在用于序列化支持。自定义类型的序列化支持不是绝对必需的。但是,如果您正实现一个控件,或正使用作为类的功能和设计一部分的序列化,则应实现 ConvertTo

若要将转换器的 ConvertTo 方法用作支持 XAML 的 TypeConverter 实现,该方法必须将支持的类型(或值)的实例作为 value 参数接受。如果 destinationType 参数为类型 String,则返回的对象必须可强制转换为 String。返回的字符串必须表示 value 的序列化值。理想情况下,如果将该字符串传递到同一转换器的 ConvertFrom 实现,则选择的序列化格式应能够生成相同的值,同时不会丢失大量信息。

如果值无法进行序列化,或者转换器不支持序列化,则 ConvertTo 实现必须返回 null,并允许在此情况下引发异常。

如果 destinationType 参数不为类型 String,则可以选择自己的转换器处理。通常,将恢复为基实现处理。

每个 TypeConverter 实现都可以有其自己对组成有效转换字符串的内容的解释,还可以使用或忽略作为参数传递的类型描述或区域性上下文。

说明:

请勿使用大括号字符,尤其是 {,其原因是它有可能作为您字符串格式的一个元素。这些字符保留为标记扩展序列的入口和出口。

实现 CanConvertTo

您的 CanConvertTo 实现应为类型 String 的 destinationType 返回 true,否则遵从基实现。

实现 CanConvertFrom

您的 CanConvertFrom 实现应为类型 String 的 sourceType 返回 true,否则遵从基实现。

应用 TypeConverterAttribute

为了将自定义类型转换器用作自定义类的活动类型转换器,必须对类定义应用 .NET Framework 属性 TypeConverterAttribute。通过属性指定的 ConverterTypeName 必须是自定义类型转换器的类型名称。如果应用了此属性,则当 XAML 处理器处理在属性类型使用您自定义类类型情况下的值时,它可以输入字符串并返回对象实例。

您还可以基于每个属性提供类型转换器。不应将 .NET Framework 属性 TypeConverterAttribute 应用到类定义,而是将其应用到属性定义(是主定义,而不是其中的 get/set 实现)。属性类型必须与自定义转换器处理的类型匹配。如果应用了此属性,当 XAML 处理器处理该属性的值时,它可以处理输入字符串并返回对象实例。如果选择使用 Microsoft .NET Framework 或某些其他库(其中无法控制类定义并无法应用 TypeConverterAttribute)中的属性类型,则每个属性类型转换器方法尤其有用。

请参见

概念

XAML 概述

标记扩展和 XAML

XAML 语法术语

参考

TypeConverter