一.再说XAML
XAML是一种专门绘制UI的语言,借助它可以把UI与运行逻辑分离开来。XAML使用标签定义UI元素,每一个标签对应.NET Framework类库的一个控件类。通过设置标签的Attribute,不仅可以对标签所对应的控件对象Property进行赋值,还可以声明名称空间,指定类名等。XAML文档是树形的,在WPF中布局设计会影响到ui的显示效果,具体的会在下一节详细说明。在此给出一个简单的例子,Xaml的代码如下:
<Window x:Class="Chap_02.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Rectangle x:Name="rectangle" Width="200" Fill="Blue"></Rectangle> <TextBox x:Name="textBox1" Width="50" Background="Red"></TextBox> </Grid> </Window>
把上面<Grid>标签换成<StackPanel>观察结果。
二.初始化对象的属性——为对象属性赋值
2.1使用Attribute为对象属性赋值
XAML是一种声明性语言,XAML编译器会为每个标签创建一个与之对应的对象,之后要对他的属性进行初始化才会有意义。所以,每个标签除了声明对象就是初始化对象的属性--即给其属性赋值。赋值方法有两种:一种是字符串简单赋值(在XAML中赋值),另外一种是使用属性元素进行复杂赋值(在.cs里面赋值)。下面的例子用xaml赋值,前台代码:
<Windowx:Class="Chap_02.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Rectangle x:Name="rectangle" Width="200" Fill="Blue"></Rectangle> </Grid> </Window>
后台代码为默认代码,用.cs赋值,其中前台代码为上面的代码的一部分,把Fill="Blue"去掉
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace Chap_02 { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); SolidColorBrush scb = new SolidColorBrush(); scb.Color = Colors.Blue; this.rectangle.Fill = scb; } } }
在这里或许你会感觉到xaml的强大了;几个字母搞定的,.cs要好多行,这个好像是白话文和古文的区别一样,各有优势和略势。下面解释一下Fill属性,其值类型是Brush,但是Brush又是一个抽象类(由于抽象类不能实例化),所以只有用抽象类的子类的实例进行赋值。既然上面用到笔刷类,下面就给出Brush的派生类及其描述:
· SolidColorBrush:使用纯 Color 绘制区域。
· LinearGradientBrush:使用线性渐变绘制区域。
· RadialGradientBrush:使用径向渐变绘制区域。
· ImageBrush:使用图像(由 ImageSource 对象表示)绘制区域。
· DrawingBrush:使用 Drawing 绘制区域。 绘图可能包含向量和位图对象。
· VisualBrush:使用 Visual 对象绘制区域。 使用 VisualBrush 可以将内容从应用程序的一个部分复制到另一个区域,这在创建反射效果和放大局部屏幕时会非常有用。
2.2使用TypeConvert类将XAML标签的Attribute与对象的Property进行映射
由于XAML的属性元素赋值形式为Attribute=value且value是一个字符串的缘故,我们前面说过Attribute和对象的Property对应,如果在后台获取对象的Property呢?如果是直接获取的话多数会看到转化失败的提示,因为Property的类型不一定为string类型的。为了解决这个问题,我们利用的是TypeConverter类,对于这个类微软官方的解释:
提供一种将值类型转换为其他类型的统一方式。 TypeConverter 通常支持字符串到对象的转换,目的是供设计环境中的属性编辑器使用或者是为了能够使用 XAML。
下面就给出一个例子来看看:
需求是这样的,我给出一个类,在XAML中的某个元素里(由于刚刚开始,所以就叫某个元素吧,到后面我们会发现他叫资源)存储一个类为Human的对象,含有名字和儿子,儿子的类型也是Human,其中在XAML里为儿子赋值为儿子的名字。然后在UI上放一个按钮,当我点击UI上的按钮时弹出儿子的名字。 XAML的代码为:
<Window x:Class="Chap_02.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Chap_02" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <local:Human x:Key="human" Child="ABC"></local:Human> </Window.Resources> <Grid> <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="56,78,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click"/> </Grid> </Window>
顺便把后台代码页贴出来吧
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.ComponentModel; namespace Chap_02 { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } //点击按钮事件 private void button1_Click(object sender, RoutedEventArgs e) { Human h =(Human) this.FindResource("human"); MessageBox.Show(h.Child.Name); } } //人类 public class Human { public string Name { get; set; } public Human Child { get; set; } } }
直接运行,点击按钮会出现异常,无法将字符串转成Human类,在Human类下面加上一个TypeConverter的派生类,重写ConvertFrom方法, 还是上代码吧!!
public class StringToHumanTypeConverter : TypeConverter { public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.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); } }
除此之外还要在Human类前加[TypeConverter(typeof(StringToHumanTypeConverter))]其中TypeConverter是TypeConverterAttribute的缩写。现在再单击按钮,应该就会弹出child的name来了。
2.3通过属性元素解决Attribute=value的复杂的value
由于value是字符串,由于种种原因字符串经常容易写错,特别是比较长或者没有规律的字符串,但是作为程序员幸运的是有属性元素(在vs平台上可以智能提示)。不明思议,属性元素就是某个标签的一个属性用元素(或者说标签)表达出来。如下面的例子,直接给出XAML代码:
<Window x:Class="Chap_02_PropertyElement.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Rectangle HorizontalAlignment="Left" Margin="73,75,0,150" Stroke="Black" Width="170"> <Rectangle.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="#FF668D2F" Offset="1"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </Grid> </Window>
运行结果时一个渐变的矩形,如果是要让我们用Fill的表达的话,那是有点难度的吧,现在用了属性元素,至少.NET平台会给我们提示甚至不用提示,用blend很简单的就出来了一个渐变效果。
2.4标签扩展
为了同一个对象赋值给两个对象的属性,或者是需要队形的属性赋一个null值等功能,现在引入标记扩展。先通过一个例子来说明吧!老规矩说需求,在一个文本框里面显示一个slider的值。效果图如下:
图1
其代码为:
<Window x:Class="xNameSpace.MarkExtensions" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MarkExtensions" Height="300" Width="300"> <StackPanel> <TextBox Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}" Margin="5"/> <Slider x:Name="slider1" Margin="5"/> </StackPanel> </Window>
主要说明是 <TextBox Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}" Margin="5"/>这一句,扩展标签对象的类型为花括号最左边的单词,花括号里面的值不需要再加括号。具体的细节不要太在意,以后的章节会再具体说明,目前只需要了解一下有这么一回事。
三、导入程序集合引用其中的名称空间
在项目里面建一个类库Common,和一个xaml项目Chap_02,然后生成。XAML中的引用名称空间和程序集的格式:
xmlns:映射名="clr-namespace:名称空间;assembly=程序集名"
对应XAML的引用为:
xmlns:common="clr-namespace:Common;assembly=Common"
<common:类名></common:类名>
四、总结
本文主要说明说明了TypeConverter和属性元素,最后介绍了导入程序集和命名空间。如有不足的地方,还请大家指出,谢谢阅读!下一节,x名称空间详解。