目录
  • 树形结构
  • 对象属性赋值语法
    • 使用标签的Attribute
    • 使用属性元素
    • 扩展:标记扩展(Markup Extensions)
    • 扩展:使用TypeConverter 类映射Atribute与Property
  • 事件处理器
  • 导入程序集及引用命名空间
  • XAML的注释

XAML使用标签来定义Ul元素(UIElement),每个标签对应NET Framework类库中的一个控件类。通过设置标签的Atribute,不但可以对标签所对应控件对象的Property进行赋值,还可以做一些额外的事件(如声明命名空间、指定类名等)。

树形结构

在界面上添加一些控件,界面如下:

界面的XAML如下所示:

<Window x:Class="LearnWpf.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:LearnWpf"mc:Ignorable="d"Title="MainWindow" Height="164.458" Width="344.578"><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="69*"/><ColumnDefinition Width="19*"/></Grid.ColumnDefinitions><TextBox HorizontalAlignment="Left" Height="23" Margin="10,33,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="245"/><Button Content="Button" HorizontalAlignment="Left" Margin="10,91,0,0" VerticalAlignment="Top" Width="245" Height="21"/><StackPanel HorizontalAlignment="Left" Height="25" Margin="10,61,0,0" VerticalAlignment="Top" Width="245" Orientation="Horizontal"><TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/><TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/></StackPanel><TextBox HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="245" /></Grid>
</Window>

可以看出UI是平面结构,XAML是树形结构,而且同一种UI布局界面的XAML代码可以有多种实现。在开发时,可以通过WPF基本类库中的VisuaTreeHelper和LogicarTreeHelper两个助手类操作XAML树。
VS2019可以通过“视图->其他窗口->文档大纲”查看XAML代码的结构,如图所示:

对象属性赋值语法

XAML是一种声明性语言,在文档只能使用标签声明对象、初始化对象的属性。XAML中为对象属性赋值共有两种语法:

  • 使用字符串(标签的Attribute)进行简单赋值
  • 使用属性元素(Property Element)进行复杂赋值。

注:能使用Attribute=Value形式赋值的就不使用属性元素

使用标签的Attribute

一个标签的Attribute里有一部分与对象的Property互相对应,如<Rectangle>标签的Fill这个Attribute与Rectangle类对象的Fill属性对应。Rectangle.Fill的类型Brush是一个抽象类,凡是以Brush为基类的类都可作为Fill属性的值。
使用字符串对Atribute进行简单赋值,让Rectangle填充成单一的蓝色,XAML代码(省略了Window标签)如下:

<Grid><Rectangle x:Name="rectangle" Fill="Blue" HorizontalAlignment="Left" Height="100" Margin="70,17,0,0" Stroke="Black" VerticalAlignment="Top" Width="100"/>
</Grid>

上面的“Blue”最终被翻译成了SolidColorBrush对象,等效C#代码如下:

SolidColorBrush sBrush = new SolidColorBrush();
sBrush.Color = Colors.Blue;
this.rectangle.Fill = sBrush;

使用属性元素

属性元素指的是某个非空标签的一个元素(夹在起始标签和结束标签之间的一些子级标签)对应这个标签的一个属性,即以元素的形式来表达一个实例的属性。
上面Attribute赋值的例子可以用属性元素的方式实现,XAML(省略了Window标签)代码如下:

<Grid><Rectangle x:Name="rectangle" HorizontalAlignment="Left" Height="100" Margin="70,17,0,0" Stroke="Black" VerticalAlignment="Top" Width="100"><Rectangle.Fill><SolidColorBrush Color="Blue"/></Rectangle.Fill></Rectangle>
</Grid>

属性元素语法的优势在属性是复杂对象时才能体现出来,比如线性渐变画刷填充矩阵代码(省略了Window标签):

<Grid><Rectangle x:Name="rectangle" HorizontalAlignment="Left" Height="100" Margin="70,17,0,0" Stroke="Black" VerticalAlignment="Top" Width="100"><Rectangle.Fill><LinearGradientBrush><LinearGradientBrush.GradientStops><GradientStop Offset="0.2" Color="LightBlue"/><GradientStop Offset="0.7" Color="Blue"/><GradientStop Offset="1.0" Color="DarkBlue"/></LinearGradientBrush.GradientStops></LinearGradientBrush></Rectangle.Fill></Rectangle>
</Grid>

扩展:标记扩展(Markup Extensions)

上面大多数赋值都是为属性生成一个新对象,当需要为对象的属性进行特殊类型赋值时就需要使用标记扩展了,如:

  • 把同一个对象赋值给两个对象的属性
  • 给对象的属性赋一个null值
  • 将一个对象的属性值依赖在其他对象的某个属性上

标记扩展是一种特殊的Atribule=Value语法,Value字符串是由一对花括号及其括起来的内容组成,XAML编译器会对这样的内家做出解析并生成相应的对象。
使用Binding类的实例将TextBox的Text属性依赖在Slider的Value上,当Slider的滑块滑动时TextBox就会显示Slider当前的值,XAML代码(省略了Window标签)如下:

<Grid><StackPanel HorizontalAlignment="Left" Height="115" Margin="10,10,0,0" VerticalAlignment="Top" Width="205"><TextBox Height="23" TextWrapping="Wrap" Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}"/><Slider x:Name="slider1" Margin="0,5,0,0"/></StackPanel>
</Grid>

Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}"就是标记扩展,对象的数据类型名是紧邻左花括号的字符串,对象的属性由一串以逗号连接的子字符串负责初始化(不加引号)
标记扩展也是对属性的赋值,完全可以使用属性标签的形式来替换标记扩展,但基本上没人这么做(太不简洁了)。
只有MarkupExtension类的派生类(直接或间接均可)才能使用标记扩展语法来创建对象,后面会主要说明下面几种:

  • MarkupExtension的直接派生类并不多,它们是:
  • System.Windows.ColorConvertedBitmapExtension
  • System.Windows.DynamicResourceExtension
  • System.Windows.ResourceKey
  • System.Windows.StaticResourceExtension
  • System.Windows.TemplateBindingExtension
  • System.Windows.ThemeDictionaryExtension
  • System.Windows.Data.BindingBase
  • System.Windows.Data.RelativeSource
  • System.Windows.Markup.ArrayExtension
  • System.Windows.Markup.NullExtension
  • System.Windows.Markup.StaticExtension
  • System.Windows.Markup.TypeExtension

扩展:使用TypeConverter 类映射Atribute与Property

有时候我们有一些自定义的类需要使用XAML语言进行声明,并允许它的Property与XAML标签的Atribute互相映射,那就需要为这些Property准备适当的转换机制
下面以自定义类Human为例演示TypeConverter的用法,XAML代码(省略了Window标签)如下:

<Window.Resources><local:Human x:Key="human" Child="AB" />
</Window.Resources>
<Grid>        <Button Content="Button" HorizontalAlignment="Left" Margin="61,40,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
//按钮事件
private void Button_Click(object sender, RoutedEventArgs e)
{Human h = (Human)this.FindResource("human");MessageBox.Show(h.Child.Name);
}/// <summary>
/// 以绑定转换器的目标类型Human(TypeConverter是TypeConverterAttribute的简写)
/// </summary>
[TypeConverter(typeof(StringToHumanlypeConverter))]
public class Human
{public string Name { get; set; }public Human Child { get; set; }
}/// <summary>
/// 字符串转目标类型Human的转换器
/// </summary>
public class StringToHumanlypeConverter : 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);}//设计时判断是否支持源类型到目标类型的转换,缺少此方法的重载会使UI设计器异常public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType){if (sourceType == typeof(string)){return true;}return base.CanConvertFrom(context, sourceType);}
}

需要注意的是TypeConverter的ConvertFrom、CanConvertFrom两个方法必须同时重载,只有前者会导致设计时界面异常、运行时数据转换正常,只有后者会导致设计时界面正常、运行时数据转换异常。

事件处理器

一个XAML标签对应着一个对象时,这个标签的一部分Atribute会对应这个对象的Property,还有一部分Attribute对应着对象的事件(Event)
标签有一个名为Click的Attribute,它对应的就是Buton类的Click事件,如下所示:

<Grid><Button x:Name="button1" Content="Button" HorizontalAlignment="Left" Margin="61,40,0,0" VerticalAlignment="Top" Width="75" Click="button1_Click"/>
</Grid>

注:右键Click="Button_Click"->“转到定义”,会自动生成一个空的事件处理函数
等效的C#代码如下所示:

Button buttonl = new Button();
buttonl.Click += new RoutedEventHandler(buton1_Click);

由于C#的partial类和XAML标签的x.Class特征,开发软件时完全可以把用于实现程序逻辑的C#代码放在一个文件里,把用于描述程序U1的XAML代码放在另一个文件里,并且让事件性Attribute充当XAML与C#之间沟通的纽带。这种将逻辑代码与UI代码分离、隐藏在UI代码后面的形式就叫作“代码后置”(Code-Behind)。当然,事件代码也可以使用标签x:Code直接写到XAML里面

导入程序集及引用命名空间

在XAML中引用命名空间的语法是:

xmlns:映射名="clr-namespace:类库中命名空间的名字;assembly=类库文件名"
  • xmlns是用于在XAML中声明命名空间的Attribute,从XML语言继承而来(XML Namespace的缩写)。
  • 冒号后的映射名是可选的,但由于可以不加映射名的默认命名空间已经被WPF的主要命名空间占用,所以所引用的命名空间都需要加上这个映射名。映射名可以自由选择,建议使用类库中命名空间的原名或者缩写
  • 引号中的字符串值确定了要引用的是哪个类库以及类库中的哪个命名空间。

使用引用命名空间中的类的语法如下:

<映射名:类名>.…</映射名:类名>

C#中也可以给命名空间设置映射名,但没什么意义,如:

using Cmn=Common;
using Cu=Controls;

XAML的注释

XAML的注释语法亦继承自XML,语法是:

<!--需要被注释掉的内容-->
  • XAML注释只能出现在标器的内容区域,即只能出现在开始标签和结来标签之阔。
  • XAML注释不能用于注释标签的Attribute。
  • XAML注释不能嵌套。

WPF之XAML语法相关推荐

  1. 《深入浅出WPF》——XAML语法及基础知识

    文章目录 一. 剖析一段简单的XAML代码 二. XAML中为对象属性赋值的语法 2.1. 使用标签的Attribute为对象进行赋值

  2. WPF学习日记(二)——XAML语法

    XAML语法 1.XAML文档的树形结构   XAML使用标签来定义UI元素,每个标签对应.NET Framework类库中的一个控件类.通过设置标签的Attribute,不但可以对标签所对应控件对象 ...

  3. wpf中xaml的类型转换器与标记扩展

    wpf中xaml的类型转换器与标记扩展 原文:wpf中xaml的类型转换器与标记扩展 这篇来讲wpf控件属性的类型转换器 类型转换器 类型转换器在asp.net控件中已经有使用过了,由于wpf的界面是 ...

  4. 基本 XAML 语法指南

    我们介绍了 XAML 语法规则,以及用于描述 XAML 语法中存在的限制或选项的术语.当出现以下情况时你会发现本主题很有用:不熟悉 XAML 语言的使用,希望加强对术语或某些语法部分的理解,或者对 X ...

  5. 第一章:初识WPF,XAML,WPF控件

    前言 总目录 本章主要介绍WPF与XAML,以及WPF的控件的基本使用,让大家先初步认识WPF. 关于WPF的官方资料:官方WPF文档1 .官方WPF文档2.官方WPF文档3.官方WPF文档4 一.W ...

  6. WPF开发XAML格式化神器

    一.概要 不知道大家在开发WPF中有没有遇到过这种情况,在编写XAML的时候会发现多人编辑或自己修修改改会导致XAML文件的内容异常的乱比如这样. 我们需要手动的去缩进空格或者换行,会导致这种比较蠢的 ...

  7. dotnet 使用 ShowMeTheXAML 显示 WPF 的 XAML 控件内容

    本文来告诉大家一个好用的控件库,这个控件库可以方便用在自己编写示例项目中使用.使用 ShowMeTheXAML 控件库可以将某段 XAML 内容作为字符串文本内容显示出来,方便让其他开发者看到界面以及 ...

  8. WPF下的语法高亮控件——AvalonEdit

    早就听闻SharpDevelop 会采用WPF作为界面,今天在网上闲逛的时候发现了其语法编辑器--AvalonEdit已经发布了,在CodeProject上也可以看到其代码了. 界面效果如下: 下载了 ...

  9. WPF基础-XAML

    XAML语言说明 xaml是微软在xml语言基础上开发出来,用于设计WPF程序UI的语言 XAML语言的初衷是为了让设计师和程序员能够干各自专业的事,即UI设计与代码逻辑分离.(逻辑有点像点后端分离, ...

最新文章

  1. mysql cluster cge (commercial)_Mysql 产品分类和版本说明
  2. Redis分布式缓存
  3. web.xml.jsf_使用JSF 2.2功能来开发可滚动,可延迟加载的Ajax数据表
  4. 我们自己搞了个数据库设计工具(客户端)
  5. EMC CTO:IT进化到“以数据为核心”的阶段
  6. 测试电脑电源是否正常的办法
  7. 42、最大子序和(python)
  8. 使用USB转485编程电缆连接西门子 S7-200的软件配置方法以及可能出现的问题
  9. Packet Tracer 思科模拟器入门教程 实验报告1
  10. Highcharts - Bar Chart Column Chart
  11. vue中.lazy 相当于change事件
  12. 【设计图交接与沟通的高效平台】上海道宁为设计师与开发者提供产品团队的互联空间——Zeplin
  13. 怎么查询上网帐号和上网口令_宽带上网账号和密码忘记了该怎么查询
  14. 深度学习中的正则化方法
  15. 批处理 检测U盘插入并自动备份文件
  16. 网络工程师教程(第一部:网络层面介绍)
  17. 蓝牙核心协议学习 -- 基带协议(Baseband)翻译最终版
  18. java属于高级语言_一文告诉你java是高级语言吗?
  19. 个人版机房收费——数据库设计
  20. 我的世界java旁观者模式_我的世界如何切换到旁观模式

热门文章

  1. Swift中文教程(一)基础数据类型
  2. FLEX:target和currentTarget属性的区别
  3. 动态规划——最大子矩阵(hdu1081)
  4. mysql 分库分表mycat部署
  5. EtherCAT1.5.2官方文档翻译-第七章
  6. CSS——Fonts(字体)
  7. CSS——id 和 class 选择器
  8. 【C++深入探索】Copy-and-swap idiom详解和实现安全自我赋值
  9. 草稿 9206需抄写 1129
  10. 爬虫-访问用户中心页面-服务端做了些什么