为对象属性赋值
- 使用标签Attribute字符串进行简单赋值
- 使用属性元素(Property Element)进行复杂赋值
使用标签为对象属性赋值
Rectangle标签中有Fill这个属性,C#中Rectangle.Fill的类型是Brush。
<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"被翻译成
SolidColorBrush sBrush = new SolidColorBrush();
sBrush.Color = Colors.Blue;
this.rectangle.Fill = sBrush;
从上面可以看出,通过Attribute=Value这种语法,有很大的限制,需要提供标签Attribute到类对象Property的转换,并且Value是字符串很难提供负责的目标对象。
使用属性元素赋值
XAML中,子标签都是父标签的一个元素,属性元素就是 某个标签的某个元素对应这个标签的一个属性,即以元素的形式来表达一个实例的属性。
<ClassName>
<ClassName.PropertyName>
...
</ClassName.PropertyName>
</ClassName>
上面的Rectangle案例可以改写为
<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会显示当前值。
<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};
其实标记扩展也可以通过属性标签来表示
<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文件中的方法
<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
- 注释不能嵌套