在代码中,您可以从各种不同的来源以各种不同的方式设置属性:
triangle.Angle1 = 45;
triangle.Angle1 = 180 * radians / Math.PI;
triangle.Angle1 = angles[i];
triangle.Angle1 = animator.GetCurrentAngle();
如果此Angle1属性为double,则所需的只是source为double或以其他方式提供可转换为double的数值。
但是,在标记中,double类型的属性通常只能从符合Double.Parse有效参数的字符串中设置。到目前为止,您唯一看到的例外是当目标property被标记为TypeConverter属性时,例如FontSize属性。
如果您可以从显式文本字符串以外的来源设置属性,则可能需要更灵活的XAML。例如,假设您要定义另一种设置Color类型属性的方法,可能使用Hue,Saturation和Luminosity值,但没有x:FactoryMethod元素的麻烦。只是随便,它似乎不可能。 XAML解析器期望设置为Color类型属性的任何值都是ColorTypeConverter类可接受的字符串。
XAML标记扩展的目的是绕过这个明显的限制。请放心,XAML标记扩展不是XML的扩展。 XAML始终是合法的XML。 XAML标记扩展只是扩展,因为它们扩展了标记中属性设置的可能性。标记扩展本质上提供特定类型的值,而不必是值的文本表示。
代码基础架构
严格来说,XAML标记扩展是一个实现IMarkupExtension的类,它是在常规Xamarin.Forms.Core程序集中定义的公共接口,但名称空间为Xamarin.Forms.Xaml:
public interface IMarkupExtension
{
object ProvideValue(IServiceProvider serviceProvider);
}
顾名思义,ProvideValue是为XAML属性提供值的方法。 IServiceProvider是.NET基类库的一部分,在System命名空间中定义:
public interface IServiceProvider
{
object GetService(Type type);
}
显然,这些信息并没有提供很多关于编写自定义标记扩展的暗示,事实上,它们可能很棘手。 (您将很快看到一个示例以及本书后面的其他示例。)幸运的是,Xamarin.Forms为您提供了几个有价值的标记扩展。 这些分为三类:
-
标记扩展是XAML 2009规范的一部分。 它们出现在具有惯用x前缀的XAML文件中,并且是:
- x:Static
- x:Reference
- x:Type
- x:Null
- x:Array
它们在包含标记扩展名称的类中实现,其中包含Extension附加的单词 例如,StaticExtension和ReferenceExtension类。 这些类在Xamarin.Forms.Xaml程序集中定义。
-
以下标记扩展源自Windows Presentation Foundation(WPF),并且除DynamicResource外,还支持Microsoft的其他XAML实现,包括Silverlight,Windows Phone 7和8以及Windows 8和10:
- StaticResource
- DynamicResource
- Binding
这些是在公共StaticResourceExtension,DynamicResourceExtension和BindingExtension类中实现的。
- 只有一个标记扩展是Xamarin.Forms独有的:与RelativeLayout一起使用的ConstraintExpression类。
尽管可以在代码中使用公共标记扩展类,但它们在XAML中才有意义。