WPF基础:(1)XMAL中为对象是属性赋值的语法
XMAL中为对象是属性赋值的语法:
- 使用标签的Attribute为对象属性赋值
- 使用TypeConverter类将XAML标签的Attribute与对象的Property进行映射
- 属性元素
- 标记扩展(Markup Extensions)
一)理解Attribute与Property
Attribute:即特性,是编程语言文法层面的东西。只与语言层面上的东西相关,与抽象出来的对象没什么关系。Attribute只是用来影响类在程序中的用法。
Property:即属性,属于面向对象理论范畴。属性是针对对象而言的。
标签式语言只是把标签与对象做了一个映射,同时把标签的Attribute与对象的Property也做了一个映射。针对标签的叫Attribute。针对对象的叫Property。
二)使用标签的Attribute为对象属性赋值
语法:Attribute=Value
注意,此处Value是字符串值。
代码段1
<!--范例-->
<!--Attribute=Value 的形式进行赋值的-->
<Window x:Class="XMAL中为对象是属性赋值.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:XMAL中为对象是属性赋值"
mc:Ignorable="d"
Title="MainWindow" Height="150" Width="280" >
<Grid>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="姓名:" HorizontalAlignment="Center" Width="40" Margin="20,0,0,0"/>
<TextBlock x:Name="tbk1" HorizontalAlignment="Center" Width="180" Margin="5" TextAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="班级:" HorizontalAlignment="Center" Width="40" Margin="20,0,0,0"/>
<TextBlock x:Name="tbk2" HorizontalAlignment="Center" Width="180" Margin="5" TextAlignment="Center" />
</StackPanel>
<StackPanel >
<Button Content="显示" Width="200" Margin="0,20,0,0" Click="Button_Click"/>
</StackPanel>
</StackPanel>
</Grid>
</Window>
上面代码中的 Content="姓名:" HorizontalAlignment="Center" Width="120" 等都是以 Attribute=Value 的形式进行赋值的。
运行以上代码:
三) 使用TypeConverter类将XAML标签的Attribute与对象的Property进行映射
如果一个类能使用XAML语言进行声明并进行赋值,有时候可能需要为这些Property准备适当Converter。
如下范例:
有一个Student类和Class类
代码段2
//学生
public class Student
{
public string MyName { get; set; }
public Class MyClass { get; set; }
}
//班级
public class Class
{
public int ClassNo { get; set; }
public int ClassMember { get; set; }
}
修改代码段1,添加一个名为stu的Student类,作为Window.Resources。
代码段1.1
<Window x:Class="XMAL中为对象是属性赋值.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:XMAL中为对象是属性赋值"
mc:Ignorable="d"
Title="MainWindow" Height="150" Width="280" >
<Window.Resources>
<local:Student x:Key="stu" MyName="徐猫" MyClass="206"/>
</Window.Resources>
<Grid>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="姓名:" HorizontalAlignment="Center" Width="40" Margin="20,0,0,0"/>
<TextBlock x:Name="tbk1" HorizontalAlignment="Center" Width="180" Margin="5" TextAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="班级:" HorizontalAlignment="Center" Width="40" Margin="20,0,0,0"/>
<TextBlock x:Name="tbk2" HorizontalAlignment="Center" Width="180" Margin="5" TextAlignment="Center" />
</StackPanel>
<StackPanel >
<Button Content="显示" Width="200" Margin="0,20,0,0" Click="Button_Click"/>
</StackPanel>
</StackPanel>
</Grid>
</Window>
添加ButtonClick事件,用于显示UI
代码段3
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Student s = (Student)this.FindResource("stu");
tbk1.Text = s.MyName;
tbk2.Text = s.MyClass.ClassNo.ToString();
}
}
运行后发生异常:
System.Windows.Markup.XamlParseException:““设置属性“XMAL中为对象是属性赋值.Student.MyClass”时引发了异常。
这是因为<local:Student x:Key="stu" MyName="徐猫" MyClass="206"/>中MyClass的Value值是字符串类型,而代码段2中Student的Myclass是一个Class类型的。
两者类型不统一,需要一个转换器——Converter。
修改代码段2
代码段2.2
//学生
public class Student
{
public string MyName { get; set; }
public Class MyClass { get; set; }
}
//班级
[TypeConverter(typeof(ClassConvert))]
public class Class
{
public int ClassNo { get; set; }
public int ClassMember { get; set; }
}
//转换器
public class ClassConvert : TypeConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string)
{
Class _class = new Class();
_class.ClassNo = Convert.ToInt32(value);
return _class;
}
return base.ConvertFrom(context, culture, value);
}
}
此时,运行后并点击按钮后的结果如下图:
四) 属性元素
属性元素:某个标签的一个元素对应这个标签的一个属性。
<ClassName>
<ClassName.PropertyName>
<!--以对象的形式为属性赋值-->
</ClassName.PropertyName>
</ClassName>
范例:
<Border BorderBrush="Red" CornerRadius="10" Height="50" Margin="0 5 0 0" BorderThickness="2" >
<Border.Background>
<SolidColorBrush Color="DarkOliveGreen" Opacity="0.5"/>
</Border.Background>
</Border>
五) 标记扩展(Markup Extensions)
是一种特殊的Attribute=Value语法,Value字符串是由一对花括号和被括内容组成。
<StackPanel Orientation="Horizontal">
<Label Content="班级:" HorizontalAlignment="Center" Width="40" Margin="20,0,0,0"/>
<TextBlock x:Name="tbk2" HorizontalAlignment="Center" Width="180" Margin="5" TextAlignment="Center" Text="{Binding Source={StaticResource stu}, Path=MyClass.ClassNo}"/>
</StackPanel>
Text="{Binding Source={StaticResource stu}, Path=MyClass.ClassNo}"就是一个扩展标签。
只有MarkupExtension的派生类才能使用标记扩展的语法来写。
System.Activities.Presentation.CachedResourceDictionaryExtension
System.Activities.XamlIntegration.DynamicUpdateMapExtension
System.Activities.XamlIntegration.PropertyReferenceExtension<T>
System.ServiceModel.EndpointIdentityExtension
System.ServiceModel.XamlIntegration.SpnEndpointIdentityExtension
System.ServiceModel.XamlIntegration.UpnEndpointIdentityExtension
System.ServiceModel.XamlIntegration.XPathMessageContextMarkupExtension
System.Windows.ColorConvertedBitmapExtension
System.Windows.Data.BindingBase
System.Windows.Data.RelativeSource
System.Windows.DynamicResourceExtension
System.Windows.Markup.ArrayExtension
System.Windows.Markup.NullExtension
System.Windows.Markup.Reference
System.Windows.Markup.StaticExtension
System.Windows.Markup.TypeExtension
System.Windows.StaticResourceExtension
System.Windows.TemplateBindingExtension
System.Windows.ThemeDictionaryExtension
- 标记扩展是可以嵌套的。
- 标记扩展具有一些简写方法。“{Binding Value}”与“{Binding Path=Value}”等价
- 标记扩展类的类名均以Extension结尾,在XAML中可以省略不写。
简化XAML技巧:
- 能使用Attribute=Value形式赋值的就不使用属性元素
- 充分利用默认属性,默认属性可以省略不写。
- 充分利用XAML的简写方法。
参开文献:《深入浅出WPF》刘铁锰