深入浅出WPF笔记——系统学习XAML语法

1:XAML文档的树形结构

树形结构对于WPF整个体系都具有非常重要的意义,它不但影响着UI的布局设计,还深刻地影响着WPF的属性(property)子系统和事件(Event)子系统等方方面面,在实践编程中,我们经常要在这颗树上进行按名称查找元素,获取父、子节点等操作,为了方便操作这颗树,WPF基本类库里为程序员准备了VisualTreeHelper和LogicalTreeHelper两个助手类,同时还在一些重要的基类里封装了一些专门用于操作这颗树的方法。

树形结构:

2:XAML中为对象属性赋值的语法

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

XAML中为队形属性赋值共有两种语法:使用字符串进行简单赋值和使用属性元素进行复杂赋值。

1:使用标签的Attribute为对象属性赋值

<Window x:Class="MyFirstApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyFirstApplication"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Rectangle x:Name="rectangle" Width="100" Height="200" Fill="Red"/>
    </Grid>
</Window>

 通过这种Attribute=Value语法赋值时,由于XAML的语法限制,Value只能是一个字符串值。这就引出了两个问题:

(1)如果一个类能使用XAML语言进行声明,并允许它的Property与XAML标签的Attribute相互映射,那就需要为这些Property准备适当的转换机制。

(2)由于Value是一个字符串,所以其格式复杂程度有限,尽管可以在转换机制里包含一定的按格式解析字符串的功能以便转换成较复杂的字符串以满足赋值要求。

第一个问题的解决方案是使用TypeConverter类的派生类,在派生类里重写TypeConverter的一些方法,第二个问题的解决办法就是使用属性元素。

2:使用TypeConverter类将XAML标签的Attribute与对象的Property进行映射。

<Window x:Class="MyFirstApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyFirstApplication"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <local:Human x:Key="human" Child="ABC"/>
    </Window.Resources>
    <Grid>
        <Button x:Name="button" Background="Red" Click="Button_Click" Width="50" Height="50">ok</Button>
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MyFirstApplication
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Human h = (Human)this.FindResource("human");
            MessageBox.Show(h.Child.Name);
        }
    }
    [TypeConverter(typeof(StringToHumanTypeConver))]
    public class Human
    {
        public string Name { get; set; }
        public Human Child { get; set; }
    }
    public class StringToHumanTypeConver : TypeConverter
    {
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if(value is string)
            {
                Human h = new Human();
                h.Name = value as string;
                return h;
            }
            return base.ConvertFrom(context, culture, value);
        }
    }
}

3:属性元素

在XAML中,非空标签均具有自己的内容(Content)。标签的内容指的就是夹在起始标签和结束标签之间的一些子级标签,每个子级标签都是父级标签内容的一个元素,简称为父级标签的一个元素。顾名思义,属性元素指的是某个标签的一个元素对应这个标签的一个属性,即以元素的形式来表达一个实例的属性。

4:标记扩展

仔细观察XAML中为对象属性赋值的语法,你会发现大多数赋值都是为属性生成一个新对象。但有时候需要同一个对象赋值给两个队形的属性,还有的时候需要给对象的属性赋一个null值,WPF甚至允许将一个对象的属性值依赖在其他对象的某个属性上。当需要为对象的属性进行这些特殊类型赋值时,就需要使用标记扩展了。

所谓标记扩展,实际上是一种特殊的Attribute=Value语法,其特殊的地方在于Value字符串是由一对花括号及其括起来的内容组成,XAML编译器会对这样的内容进行解析、生成相应的对象。

3:事件处理器与代码后置

在.NET事件处理机制中,可以为对象的某个事件指定一个能与该事件匹配的成员函数,当这个事件发生时,.NET运行时会去调用这个函数,即表示对这个事件的响应和处理。因此,我们把这个函数称为“事件处理器”。WPF支持在XAML里为对象的事件指定事件处理器,方法是使用事件处理器的函数名为对应对象事件的Attribute进行赋值。

当我们为一个XAML标签的事件性Attribute进行赋值时,XAML编辑器会自动为我们生成相应的事件处理器。事件处理器是使用C#编写的函数。

C#语言编写的代码应该用于处理程序的逻辑,需要让它与表示UI的XAML代码分开。由于C#支持partial类,XAML标签又可以使用x:Class特征指定将由XAML代码解析生成的类哪个类合并,因此,我们完全可以把用于时间程序逻辑的C#代码放在一个文件里,把用于描述程序UI的XAML代码放在另一个文件里,并且让事件性Attribute充当XAML与C#之间沟通的纽带,这种将逻辑代码与UI代码分离、隐藏在UI代码后面的形式就叫做“代码后置”。

4:导入程序集和引用其中的命名空间

大多数情况下,根据架构设计一个程序会被分成若干个相对独立的模块来编写,每个模块可以独立编译、进行版本升级。模块与模块之间有时会有存在一些依赖关系,即有些模块需要“借用”其他模块中的功能。.NET的模块成为程序集。

想在自己的程序里引用类库,需要分三步来做:

(1)编写类库项目并编译得到.dll文件或者获取别人编译的.dll文件。

(2)将类库项目或者.dll文件引用进自己的项目。

(3)在C#和XAML中引用类库中的命名空间。

在XAML中引用名称空间的语法:xmlns:映射名=“clr-namespace:类库中名称空间名字;assembly=类库文件名”

(1)xmlns是用于在XAML中声明中名称空间的Attribute,它从XML语言继承而来,是XML Namespace的缩写。

(2)冒号后面的映射名是可选的,但由于可以不加映射名的默认名称空间已经被WPF的主要名称空间占用,所以所引用的名称空间都需要加上这个映射名。

(3)引号中的字符串值确定了你要引用的是哪个类库以及类库中哪个名称空间。

5:XAML的注释 

XAML注释只能出现在标签的内容区域,即只能出现在开始标签和结束标签之间。

XAML注释不能用于注释标签的Attribute。

XAML注释不能嵌套。

 

参考教材书:深入浅出WPF 刘铁猛  著

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值