2.XAML语法

2.XAML语法

为对象属性赋值

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

使用标签为对象属性赋值

Rectangle标签中有Fill这个属性,C#中Rectangle.Fill的类型是Brush。

1
2
3
4
5
6
7
8
9
10
11
12
<Window x:Class="WpfApp3.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:WpfApp3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Rectangle x:Name="rectangle" Width="200" Height="120" Fill="Blue"></Rectangle>
</Grid>
</Window>

上面的Fill=”Blue”被翻译成

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

从上面可以看出,通过Attribute=Value这种语法,有很大的限制,需要提供标签Attribute到类对象Property的转换,并且Value是字符串很难提供负责的目标对象。

使用属性元素赋值

XAML中,子标签都是父标签的一个元素,属性元素就是 某个标签的某个元素对应这个标签的一个属性,即以元素的形式来表达一个实例的属性

1
2
3
4
5
<ClassName>
<ClassName.PropertyName>
...
</ClassName.PropertyName>
</ClassName>

上面的Rectangle案例可以改写为

1
2
3
4
5
<Rectangle x:Name="rectangle" Width="200" Height="120">
<Rectangle.Fill>
<SolidColorBrush Color="Blue"/>
</Rectangle.Fill>
</Rectangle>

简化XAML的技巧

  • 能使用Attribute=Value形式的就使用这种形式
  • 充分利用默认,如StartPoint=”0,0”和StartPoint效果类似
  • 利用XAML简写方式,如把集合元素直接写到属性元素的内容里

标记扩展

有时需要把同一个对象赋给两个对象的属性,有时需要给对象的属性赋值null。

示例,将TextBox的Text值与Slider的Value绑定,当滑动slider时,TextBox会显示当前值。

1
2
3
4
5
6
7
8
9
10
11
12
13
<Window x:Class="WpfApp3.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:WpfApp3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBox Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}" Margin="5"></TextBox>
<Slider x:Name="slider1" Margin="5"></Slider>
</StackPanel>
</Window>
  • 当遇到{}花括号时,会将内容转为相应的对象
  • 类型名称为挨着左侧花括号的字符串
  • 对象的属性由一串以逗号连接的子字符串负责初始化

很像Binding binding=new Binding(){Source=slider1,Mode=BindingMode.OneWay};

其实标记扩展也可以通过属性标签来表示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Window x:Class="WpfApp3.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:WpfApp3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBox Margin="5">
<TextBox.Text>
<Binding ElementName="slider1" path="Value" Mode="OneWay">
</TextBox.Text>
</TextBox>
<Slider x:Name="slider1" Margin="5"></Slider>
</StackPanel>
</Window>

绑定在C#的用法txtbox.SetBinding(TextBox.TextProperty,new Binding("Value"){ Source=slider1, Mode = BindingMode.TwoWay });

并不是所有的对象都能使用标记扩展,只有实现了MarkupExtension的类才可以。

标记扩展注意事项

  • 标记扩展是可以嵌套的,如 Text="{Binding Source={StaticResource myDataSource},Path=Value,Mode=OneWay}"
  • 标记扩展有一些简写语法,如{Binding Value,...}和{Binding Path=Value,...}等价,,前者为固定位置参数,后置为具名参数,这和类的构造函数有关
  • 标记扩展类的类名都以Extension为后缀,但在XAML中可以不写后缀

事件处理器与代码后置

以button为例,<Button x:Name="btn" Click="Button_Click"></Button>,在对应的.xaml.cs文件中会增加private void Button_Click(object sender, RoutedEventArgs e)方法。

将后置代码放到xaml文件中的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<Window x:Class="WpfApp3.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:WpfApp3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<Button x:Name="btn" Click="Button_Click"></Button>
</StackPanel>

<x:Code>
<![CDATA[
private void Button_Click(object sender, RoutedEventArgs e)
{
....
}
]]>
</x:Code>
</Window>

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

xmlns:映射名="clr-namespase:类库中的命名空间; assembly=类库文件名(不用写.dll)"

一旦引入,就可以使用命名空间中的类,使用方法<映射名:类名>..</映射名:类名>,如<controls:MyButton x:Name="btn"/>

XAML注释

<!--需要被注释的内容 -->

  • 注释只能出现在标签中
  • 不能注释标签的Attribute
  • 注释不能嵌套
作者

步步为营

发布于

2024-05-08

更新于

2025-03-15

许可协议