1、元素属性

xaml是一种声明性语言,xaml编译器会为每一个标签创建一个与之对应的对象。对象创建出来之后要对它的属性进行必要的初始化之后才有使用意义。
因为xaml语言不能写程序运行逻辑,所以一份xaml文档除了使用标签声明对象,另外一个功能就是初始化对象的属性了。
在xaml中为对象属性赋值共有两种方法:

  • 使用字符串进行简单赋值;
  • 使用属性元素进行复杂赋值。

2、使用标签的attribute为对象属性赋值

我们已经知道,标签中的attribute里面有一部分与对象的property互相呼应。
我们首先学习使用字符串对attribute进行简单赋值,将rectangle填充成单一的颜色。

<grid>
        <rectangle name="myrectangle" width="100" height="100" fill="aqua"></rectangle>
</grid>

 在xaml编译器中,“aqua” 这个字符串被翻译成了一个solidcolorbrush对象并赋值给了myrectangle对象。翻译成c#代码就是:

private void window_loaded(object sender, routedeventargs e)
{
    solidcolorbrush colorbrush = new solidcolorbrush();
    colorbrush.color = colors.aqua;
    myrectangle.fill = colorbrush;
}

3、使用typeconverter类进行属性映射

在上面的例子中我们使用attribute=value语法赋值时,由于xaml语法限制,value只能是一个字符串值。那么就会引发两个问题:

  • 如果一个类能使用xaml语言进行声明,并允许它的property与xaml标签的attribute互相映射,那么就需要为这个类的property准备适当的转换机制。
  • 由于value是一个字符串,所以其格式复杂程度有限。面对格式复杂的字符串就难以满足赋值需求。

我们举一个简单的栗子来演示第一个问题:下面的代码xaml编译器会给我们提示无法将字符串转换成huamn类型。

<window.resources>
    <my:human x:key="human" child="dsa" />
</window.resources>

(1)属性转换

使用typeconverter的派生类,在派生类里面重写typeconverter的一些方法最终来解决转换问题:

  • 准备一个我们自定义的类human。
  • 新建一个实现了typeconverter接口的类。
  • 在human类的首部加上[typeconverterattribute(typeof(stringtohumantypeconverter))]特性。

  自定义human类:

[typeconverterattribute(typeof(stringtohumantypeconverter))]
public class human
{
    public string name { get; set; }
    public human child { get; set; }
}

  typeconverter派生类:

public class stringtohumantypeconverter : typeconverter
{
    public override object convertfrom(itypedescriptorcontext context, cultureinfo culture, object value)
    {
        if (value is string)
        {
            human human = new human();
            human.name = value as string;
            return human;
        }
        return base.convertfrom(context, culture, value);
    }
}

通过以上操作我们就将普通字符串翻译成合适类型的值并赋值给元素的属性。

(2)属性元素进行复杂赋值

在xaml中,每个子级标签都是父级标签内容的一个元素,简称父级标签的一个元素。

属性元素是指:某个标签的一个元素对应了该标签的一个属性,即属性元素是以元素的形式表达了一个实例的属性。

我们使用代码可以描述为:

下面给出一个使用属性元素的简单的代码示例:

<rectangle name="myrectangle" width="100" height="100" >
    <rectangle.fill>
        <solidcolorbrush color="aqua"/>
    </rectangle.fill>
</rectangle>

(3)使用属性元素的好处

虽然使用字符串为对象属性赋值与使用属性元素为对象属性赋值相比,属性元素的代码会比较冗长,但这仅是相较比较简单的属性赋值而言的。遇到属性复杂的对象时,属性元素的好处就体现出来了。比如我们使用渐变画刷填充矩形。

<rectangle name="myrectangle" width="100" height="100">
    <rectangle.fill>
        <lineargradientbrush>
            <lineargradientbrush.startpoint>
                <point x="0" y="0"></point>
            </lineargradientbrush.startpoint>
            <lineargradientbrush.endpoint>
                <point x="1" y="1"></point>
            </lineargradientbrush.endpoint>
            <lineargradientbrush.gradientstops>
                <gradientstopcollection>
                    <gradientstop offset="0.2" color="lightcyan"/>
                    <gradientstop offset="0.4" color="aliceblue"/>
                    <gradientstop offset="0.7" color="blue"/>
                    <gradientstop offset="0.9" color="red"/>
                </gradientstopcollection>
            </lineargradientbrush.gradientstops>
        </lineargradientbrush>
    </rectangle.fill>
</rectangle>

xaml代码效果图: