XAML (Extensible Application Markup Language) 可扩展应用程序标记语言是一种基于 XML 的标记语言,以声明形式实现应用程序的外观。 通常用它创建窗口、对话框、页和用户控件,并填充控件、形状和图形,且自身即可实现动画效果(通过blend
生成XAML)。
XAML中每个标签在运行时都会创建一个实例。 例如, Window
元素被转换为 Window
类的实例,该类的 Title
属性是 Title
特性的值。
命名空间 xmlns (XML Namespace)
xmlns[:自定义映射名] = "对应的命名空间"
例如想引入类库文件MyClass.dll中的命名空间ABC,则
xmlns:abc="clr-namespace:ABC;assembly=MyClass"
//效果类似于 using ABC = abc;
用于声明命名空间,如下xmlns
声明的默认命名空间,x:Class
中的内容则属于xmlns:x
声明的命名空间。其中配置的内容并非网址,而是一个XAML内置的一个对应关系,该内容对应了多个命名空间。
通过在AssemblyInfo.cs
中添加[assembly:xmlnsDefinition("www.xxx.com","wpfLibrary")]
也可以将自己的网址设置成一个命名空间的对应。
经过声明的命名空间下的类可以直接作为标签被使用
...
为XAML的对象属性赋值
- 使用字符串进行简单赋值
- 使用属性元素进行复杂赋值
当属性是复杂对象时有优势
- 标记扩展
通过"{Binding XXX=XXX}"
的方式将TextBox
的属性依赖在Slider
的Value
上
或改用属性元素
X名称空间中的属性
x:Class
x:Class
本身不是对象的成员,而是从x
命名空间中拿出来硬贴上去的,且只能用于根节点
拥有x:Class
的标签会自动解析为一个类名为x:Class
的值的partial
类(称为代码隐藏类),其嵌套的标签会被解析为其派生类,编译时会和.cs
文件中的同名partial
类合并。
拥有x:Class
的标签解析后的类自动拥有InitializeComponent
方法,用于初始化窗体组件,将标记中定义的 UI 与代码隐藏类合并在一起。
通过Name
属性在.cs
中获取xaml
中对应元素。
- x:ClassModifier
只能给有x:Class
属性的标签添加,用于设置该类的访问权限
x:Name
通常可与Name
互换。
当一个标签具有x:Name
时,除了生成对应实例外还会为这个实例声明一个引用变量,变量名即x:Name
的值
- x:FieldModifier
拥有x:Name
的XAML标签实例,访问权限默认为internal
。通过x:FieldModifier
可以设置为public
等。
x:Key 与 资源
为资源字典贴上用于检索的索引。
hello this is String
在方法中也能获取资源
String myString = this.FindResource("myString") as String;
- x:Shared
若为true
,每次通过x:Key
获取的是同一个对象,否则为一个新的副本。默认为true
。
x名称空间中的标记扩展
x:Type,x:Null 与 Style
当需要指定某值为null
时使用x:Null
如已经指定了所有Button
的Style
,但有一个不需采用该Style
时
x:Static
在XAML中直接使用类的static成员
...
public static string ButtonContent= "Click Me";
x:Array 与 ListBox
x:Array
用于暴露一个指定类型的ArrayList
/List
实例
1
2
等价于
...
listbox.ItemsSource = new List(new []{"1","2"});
等价于
1
2
控件与布局
有些控件的内容是一个集合,如StackPanel
的内容属性是Children
,ListBox
的内容属性是Items
,当通过属性元素赋值时可以省略该内容属性的标签。
ContentControl基类
包括Window
, ScrollViewer
,各种Button
,CheckBox
等
- 均具有内容属性
Content
- 内部最多只能包含一个元素
Button
表示 Windows 按钮控件,该按钮对 Click
事件作出反应
- Click 绑定事件
- ClickMode 触发方式
- Hover => mouseover
- Press => mousedown
- Release => mouseup
ItemsControl 基类
包括Menu
, ContextMenu
,ComboBox
,ListBox
,TabControl
等
- 内容属性为
Items
或ItemsSource
- 内容应为一个集合,且会自动被对应的条目容器进行包装
如ListBox
的条目容器为ListBoxItem
,因此以下两种写法等效
- DisplayMemberPath 属性
规定展示数组中每个对象的某个属性
TextBlock 和 TextBox
用于文本展示
- TextBlock
具有丰富的格式/排版控制
内容属性为Inlines
- TextBox
支持用户自己编辑
内容属性为Text
Panel基类与UI布局
内容属性均为Children
Grid 网格
类似Table,适用于行列对齐等
默认ColumnDefinition
拥有Width="1*"
,RowDefinition
拥有Height="1*"
- 取值若为
px
,px
可省略 - 若为
Auto
,则由其内容撑开,无内容则不占空间(可用Min-Width
/Min-Height
设置最小值) - 若为
*
,则由剩余空间按值分配(类似于flex的伸缩占比)
hello
...
myGrid.ColumnDefinitions.Add(new ColumnDefinition());
StackPanel
类似
- Orientation 元素排列方式
Horizontal/Vertical - HorizontalAlignment 元素对齐方式
Left/Center/Right/Stretch - VerticalAlignment 元素对齐方式
Top/Center/Bottom/Stretch
Canvas
类似
其中的每个标签通过设置Canvas.Left
和Canvas.Top
属性来确定位置
DockPanel
内部元素通过DockPanel.Dock
选择泊靠方向(类似浮动,但具有四个方向)
- 最后一个子元素的
DockPanel.Dock
会被忽略,将尽量撑满整个DockPanel
(可通过设置LastChildFill="false"
禁用该功能)
1
2
3
WrapPanel
流式布局,排满一行自动换行(类似子元素全为inline-block
)
通过HorizontalAlignment
和VerticalAlignment
可以设置子元素整体在WrapPanel
中的位置(不影响子元素间的相对位置关系)
1
2
3
4
5
动态修改XAML
Grid grid = new Grid();
grid.ColumnDefinitions.Add(new ColumnDefinition());
grid.ColumnDefinitions.Add(new ColumnDefinition());
grid.ColumnDefinitions.Add(new ColumnDefinition());
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());
Button button = new Button() { Content="hello"};
Grid.SetColumn(button, 1);
Grid.SetRow(button, 1);
grid.Children.Add(button);
Content = grid;
事件处理器
一个XAML标签对应一个对象,标签的一部分属性对应对象的属性,另一部分则对应对象的事件。如:
约等于
private void Button_Click(object sender, RoutedEventArgs e){}
Button button = new Button();
button.click+=new RoutedEventHandler(Button_Click);
在事件中获取对象可以直接使用x:Name
的值,也可以使用形参中的sender
(即为事件的绑定者),配合.Children[0]
等选取标签。
定位
- Margin
按照左上右下依次定义,默认为"0,0,0,0"
- HorizontalAlignment
水平定位,决定了Margin优先用左右哪个值,默认为"Left"
- VerticalAlignment
垂直定位,决定了Margin优先用上下哪个值,默认为"Top"