WPF.XAML语法

 本来想写x名称空间详解,但是看了很多语法还需要好好的看一下,所以就等到下一篇了。如果文章中有不懂的话,可以留言,或者是等到下一篇的时间回头看看,应该就会明白了。

一.再说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的值。效果图如下:

WPF.XAML语法

图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名称空间详解。

WPF.XAML语法

上一篇:13-3 Window下Docker环境安装


下一篇:C#(2):Xpath导航器XpathNavigator 、System.Xml.XPath