第七章:XAML vs. code(2)

简介: 属性和特性(估且叫特性吧)这里是一个Xamarin.Forms标签在代码中实例化和初始化,就像它可能出现在页面类的构造函数中一样: new Label { Text = "Hello from Code!", IsVisible = true, Opacity = 0.

属性和特性(估且叫特性吧)
这里是一个Xamarin.Forms标签在代码中实例化和初始化,就像它可能出现在页面类的构造函数中一样:

new Label
{
    Text = "Hello from Code!",
    IsVisible = true,
    Opacity = 0.75,
    HorizontalTextAlignment = TextAlignment.Center,
    VerticalOptions = LayoutOptions.CenterAndExpand,
    TextColor = Color.Blue,
    BackgroundColor = Color.FromRgb(255, 128, 128),
    FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
    FontAttributes = FontAttributes.Bold | FontAttributes.Italic
};

这是一个非常相似的标签,在XAML中实例化和初始化,您可以立即看到它比等效代码更简洁:

<Label Text="Hello from XAML!"
       IsVisible="True"
       Opacity="0.75"
       HorizontalTextAlignment="Center"
       VerticalOptions="CenterAndExpand"
       TextColor="Blue"
       BackgroundColor="#FF8080"
       FontSize="Large"
       FontAttributes="Bold,Italic" />

Xamarin.Forms类(如Label)将成为XAML中的XML元素。 诸如Text,IsVisible等属性在XAML中成为XML属性。
要在XAML中实例化,像Label这样的类必须有一个公共无参数的构造函数。 (在下一章中,您将看到有一种技术可以将参数传递给XAML中的构造函数,但通常用于特殊用途。)在XAML中设置的属性必须具有公共设置访问器。 按照惯例,空格围绕代码中的等号但不包含在XML(或XAML)中,但您可以根据需要使用尽可能多的空格。
XAML的简洁结果主要来自属性值的简洁 - 例如,使用单词“Large”而不是对Device.GetNamedSize方法的调用。 这些缩写不是内置到XAML分析器中的。 XAML解析器由专门为此定义的各种转换器类来辅助。
当XAML解析器遇到Label元素时,它可以使用反射来确定Xamarin.Forms是否具有名为Label的类,如果是,则可以实例化该类。 现在它已准备好将该对象初始化。 Text属性是字符串类型,属性值只是分配给该属性。
由于XAML是XML,因此可以使用标准XML语法在文本中包含Unicode字符。 在十进制Unicode值前加上&#(或者用十六进制Unicode值并且用&#x),然后用分号表示:

Text="Cost &#x2014; &#x20AC;123.45"

这些是em-dash和欧元符号的Unicode值。 要强制换行,请使用换行符&#x000A或(因为不需要前导零)&#xA,或者使用十进制&#10。
尖括号,&符号和引号在XML中有特殊含义,因此要将这些字符包含在文本字符串中,请使用以下标准预定义实体之一:

-  &lt; 是 <
- &gt; 是 >
- &amp; 是 &
- &apos; 是 '
- &quot; 是 "

HTML预定义的实体,例如&nbsp; 不被支持。 对于不间断的空间,请改用&#xA0;;
另外,在第10章“XAML标记扩展”中,您会发现花括号({和})在XAML中有特殊含义。 如果您需要使用左花括号开始一个属性值,请使用一对花括号({}),然后左花括号开始。
回到示例:Label的IsVisible和Opacity属性的类型分别为bool和doubles,并且这些属性与您预期的一样简单。 XAML解析器使用Boolean.Parse和Double.Parse方法来转换属性值。 Boolean.Parse方法不区分大小写,但通常布尔值在XAML中被大写为“True”和“False”。 Double.Parse方法传递一个CultureInfo.InvariantCulture参数,所以转换不依赖于程序员或用户的本地文化。
Label的HorizontalTextAlignment属性是TextAlignment类型,它是一个枚举。 对于任何属于枚举类型的属性,XAML解析器使用Enum.Parse方法将字符串转换为值。
VerticalOptions属性是LayoutOptions类型的结构。 当XAML解析器使用反射引用LayoutOptions结构时,它会发现该结构具有定义的C#:

[TypeConverter (typeof(LayoutOptionsConverter))]
public struct LayoutOptions
{
    …
}

(注意!这个讨论涉及两种类型的特性:XML特性,例如HorizontalTextAlignment和C#特性,例如TypeConverter。)
TypeConverter特性由名为TypeConverterAttribute的类支持。 LayoutOptions上这个特殊的TypeConverter特性引用了一个名为LayoutOptionsConverter的类,该类来自一个名为TypeConverter的公共抽象类,该类定义了名为CanConvertFrom和ConvertFrom的方法。 当XAML解析器遇到此TypeConverter特性时,它将实例化LayoutOptionsConverter。 XAML中的VerticalOptions特性被分配了字符串“Center”,因此XAML解析器将该“Center”字符串传递给LayoutOptionsConverter的ConvertFrom方法,并弹出一个LayoutOptions值。 这被分配给Label对象的VerticalOptions属性。
同样,当XAML解析器遇到TextColor和BackgroundColor属性时,它将使用反射来确定这些属性的类型为Color。 Color结构也用TypeConverter特性进行装饰:

[TypeConverter (typeof(ColorTypeConverter))]
public struct Color
{
    …
}

你可以创建一个ColorTypeConverter的实例,并在代码中进行实验。 它接受多种格式的颜色定义:它可以将诸如“Blue”的字符串转换为Color.Blue值,并将“Default”和“Accent”字符串转换为Color.Default和Color.Accent值。 Color?TypeConverter还可以解析编码红 - 绿 - 蓝值的字符串,如“#FF8080”,它是一个红色值为0xFF,绿色值为0x80,蓝色值也为0x80的值。
所有数字RGB值都以数字符号前缀开头,但该前缀后面可以跟随八位,六位,四位或三位十六进制数字,用于指定具有或不具有Alpha通道的颜色值。 这是最广泛的语法:

BackgroundColor="#aarrggbb"

每个字母代表一个十六进制数字,按照alpha(不透明度),红色,绿色和蓝色的顺序排列。 对于alpha通道,请记住0xFF是完全不透明的,0x00是完全透明的。 这里是没有Alpha通道的语法:

BackgroundColor="#rrggbb"

在这种情况下,alpha值被设置为0xFF以获得完全不透明度。
其他两种格式允许您为每个通道只指定一个十六进制数字:

ackgroundColor="#argb"
BackgroundColor="#rgb"

在这些情况下,重复该数字以形成该值。 例如,#CF3是RGB颜色0xCC-0xFF-0x33。 这些短格式很少使用。
Label的FontSize属性的类型是double。 这与LayoutOptions和Color类型的属性有点不同。 LayoutOptions和Color结构是Xamarin.Forms的一部分,所以它们可以用C#TypeConverter属性标记,但不可能用TypeConverter属性标记.NET Double结构,仅用于字体大小!
相反,Label类中的FontSize属性具有TypeConverter特性:

public class Label : View, IFontElement
{
    …
    [TypeConverter (typeof (FontSizeConverter))]
    public double FontSize
    {
    }
   
}

FontSizeConverter类确定传递给它的字符串是否是NamedSize枚举的成员之一。 如果不是,FontSizeConverter假定该值是双精度值。
示例中设置的最后一个属性是FontAttributes。 FontAttributes属性是名为FontAttributes的枚举,并且您已经知道XAML解析器会自动处理枚举类型。 但是,FontAttributes枚举具有如下所示的C#Flags特性集:

[Flags]
public enum FontAttributes
{
    None = 0,
    Bold = 1,
    Italic = 2
}

XAML解析器因此允许使用逗号分隔多个成员:

FontAttributes="Bold,Italic"

XAML解析器的机械性质的演示应该是非常好的消息。 这意味着您可以在XAML中包含自定义类,并且这些类可以具有自定义类型的属性,或者属性可以是标准类型,但允许其他值。 您所需要的只是使用C#TypeConverter特性标记这些类型或属性,并提供从TypeConverter派生的类。

目录
相关文章
|
JavaScript Android开发 索引
第八章:代码和XAML协调一致5
点按手势 Xamarin.Forms按钮响应手指点击,但您实际上可以从任何派生自View的类中获取手指点击,包括Label,BoxView和Frame。 这些点击事件不会内置到View类中,但View类会定义名为GestureRecognizers的属性。
1285 0
|
JavaScript Android开发
|
JavaScript Android开发 iOS开发
|
XML JavaScript Android开发
|
XML JavaScript C#
第七章:XAML vs. code(3)
属性元素语法这里有一些C#与第4章中的FramedText代码相似。在一个语句中,它实例化一个Frame和一个Label,并将Label设置为Frame的Content属性: new Frame { OutlineColor = Color.
892 0
|
程序员 C# Android开发
第七章:XAML vs. code(1)
毫无疑问,C#是世界上有史以来最伟大的编程语言之一。 您可以在C#中编写完整的Xamarin.Forms应用程序,并且可以想象,您已经发现C#非常适合Xamarin.Forms,您甚至没有考虑过使用其他任何东西。
1838 0
|
JavaScript Android开发 iOS开发
|
JavaScript API Android开发

热门文章

最新文章