初学WPF(二)——XAML

本文详细介绍了XAML(Extensible Application Markup Language)与WPF(Windows Presentation Foundation)之间的关系及各自的特点。从XAML的基本语法入手,对比了XAML与HTML的不同之处,并探讨了XAML与WPF如何独立或相互配合使用。

 XAML,全称Extesible Application Markup Language,是一种与HTML和XML很相像的语言(或者可以说是HTML和XML的结合体),通过XAML可以对界面中控件及其各种属性进行定义。虽然一般在创建WPF程序后会自成XAML文件及其对应的cs代码文件,但是XAML与WPF并不是依附的关系,也就是说XAML文件可以单独使用(在一定条件下,比如没有Click这样的事件,很像.html文件),WPF程序中也不并要求一定有XAML文件。

XAML和HTML比较

由于XAML跟HTML很像,因此下面对两个代码做一个比较。

HTML源代码

View Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title></title> 
</head> 
<body> 
    <button>123</button> 
</body> 
</html>

 

XAML代码(窗体)

View Code
<Window x:Class="BasicControls.BrushExample" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="BrushExample" Height="300" Width="300"> 
    <Grid> 
        
    </Grid> 
</Window>


看上面XAML代码可以发现其与HTML语言的第一个不同:在XAML中只能有一个根节点,这与XML一样,在WPF中,只能使用以下几个元素作为顶级元素:

1.Window元素:WPF窗体程序

2.Page元素:WPF网页程序

3.Application:用于对应用程序进行配置

4.ResourceDictionary:只能在资源字典文件中使用

其实可以把XAML的根元素看成是HTML代码中<!DOCTYPE …>标签、<head>标签与<body>标签的结合体,在XAML的根元素中,不仅使用xmlns定义了命名空间,也表示内容的开始,同时还包含了窗体(或页面)的标题(根元素为<Application>除外)。因此理解XAML语言很容易,有些HTML语言基础的人均可以写出XAML的代码。

 

在根元素中还有一些要事情要注意。首先在上面的XAML代码中出现的x:Class=”BasicControls.BurshExample”,这是在告诉XAML解析器,需要在BasicControls命名空间下生成一个BushExample的类,该类继承Windows基类(窗体程序如此;如果根元素为Page则继承自Page类;如果根元素为Application则继承自Application类),同时将XAML代码与这个类联系起来。

其次,上面XAML代码中xmlns:x=”…”,这可以算是一种特殊的表达方式。引号内的内容为名称空间,为了后面代码中表达的方便,使用x这个字母来代替引号中的内容。这个有点类似于写C#代码时,如果我们在定义一个变量时写”System.Collections.Generic.List<int> list;“时比较麻烦,因此使用在最前面写上”System.Collections.Generic;”,在代码中只写”List<int> list;”这样更方便也不易出错的表达方式。通过将名称空间命名为x,在后面需要用名称空间时就可以用x来代替,如之前提到x:Class。如果想在文件中声明System这个名称空间,并且在代码中使用sys代替System这个名称,可以进行如下定义:

xmlns: sys=”clr-namespace: Sysetm; assembly=mscorlib”


其中assembly是名称空间所在程序集的名称,如果是当前项目中的名称空间,assembly可以省略。声明完成后就可以在直接使用了,如<sys: XXX>…</sys: XXX>

由于XAML的这种特性在给元素命名的时候有了一种新的方式。在HTML中是给元素的Name属性赋值,如<button name=”btnOK”/>,在XAML中,不仅仅支持这种方式,还可以使用XAML中的Name特性进行命名,如<Button x:Name=”btnOK”>。这两种方式是等价的,但实现的机理不一样。在后一种表述方式中,XAML会添加如下字段,为相应的类生成下面的一部分:

private System.Window.Controls.Button btnOK;


而对于前一种方式,使用RuntimeNameProperty特性修饰过后才能正常工作。因为两种是等价的,因此使用哪种方式进行命名均可以。

 

与其他语言一样,在XAML中有特殊的字符:<、>、&、””,这些字符无法在界面上正常显示,如果要显示它们需要使用特定字符编码对他们进行表达,这个与HTML语言中一样。

 

XAML与HTML在语法上最后一块差异比较大的是控件属性的表达上,这一部分放到后面介绍WPF属性时统一介绍。

 

XAML与WPF

之前也提到XAML与WPF是相互补充又相互独立的技术。XAML在一定条件下可以独自使用,而WPF也可以在不使用XAML的前提下完成程序加载和编译。

 

1.XAML的独立性

单独使用XAML也可以运行,使用浏览器就可以打开这个文件,但是需要满足一定的条件,以下面的代码为例:

View Code
<Window x:Class="BasicControls.BrushExample" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BrushExample" Height="300" Width="300"> 
<Grid> 
<Button Content=”Click Me” Click=”button1_Click”/> 
</Grid> 
</Window>


如果要让上面的代码在浏览器中正常运行,需要做以下三步:

1.在根元素上删除类特性,即将x:Class=”…”这部分删除。

2.删除所有关联事件处理程序的特性,即将Click=”button1_Click”删除

3.将Window标签改为Page。因为浏览器只能显示页面,不能显示单独的窗口

修改后的代码如下:

View Code
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BrushExample" Height="300" Width="300"> 
<Grid> 
<Button Content=”Click Me“/> 
</Grid> 
</Page>

这样,XAML文件就可以在页面上正常的显示了。

 

2.WPF的独立性

在WPF中,如果没有XAML文件,程序也可以制作出一个窗口程序。

新建一个控制台项目LoadAndCompileXAML,在里面建一个类文件:CodeOnly.cs。代码如下:

View Code
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text;

namespace LoadAndCompileXAML 
{ 
    class CodeOnly 
    { 
    } 
}

要将CodeOnly这个类做出传统窗口程序的效果,要做以下几个步骤:

1.在项目中添加如下引用:WindowBase、PresentationCore和PresentationFramework

2.在类中添加命名空间:System.Windows、System.Windows.Markup和System.Windows.Controls

3.该类需要继承自Window类

4.一般在建立窗口程序时,系统会自动在构造函数中添加InitializeComponent()方法。此方法定义了窗体上的控件和它们动作发生时对应的事件名称。因此在这个类的构造函数中添加初始化控件的方法,并在类中手动输入控件的布局、及其动作发生时对应的事件名称等。

5.添加事件内容,例如按钮单击事件Button_Click的事件内容

完成后的代码如下:

View Code
using System.Windows;   
using System.Windows.Markup; 
using System.Windows.Controls; 

namespace LoadAndCompileXAML 
{ 
    class CodeOnly : Window 
    { 
        private Button button1;

        public CodeOnly() 
        { 
            InitializeComponent(); 
        }

        private void InitializeComponent() 
        { 
            // Configure the form. 
            this.Width = this.Height = 285; 
            this.Left = this.Top = 100; 
            this.Title = "Code-Only Window";

            // Create a container to hold a button. 
            DockPanel panel = new DockPanel();

            // Create the button. 
            button1 = new Button(); 
            button1.Content = "Please click me."; 
            button1.Margin = new Thickness(30);

            // Attach the event handler 
            button1.Click += button1_Click;

            // Place the button in the panel. 
            IAddChild container = panel; 
            container.AddChild(button1);

            // Place the panel in the form 
            container = this; 
            container.AddChild(panel); 
        }

        private void button1_Click(object sender, RoutedEventArgs e) 
        { 
            button1.Content = "Thank you."; 
        }

  }
}

为了在运行程序时让窗口显示出来,对Program.cs文件中的代码也要做相应的修改。修改后的代码如下:

View Code
class Program : Application //添加System.Xaml的引用 
{ 
    [STAThread] 
    static void Main() 
    { 
        Program app = new Program(); 
         
        app.MainWindow = new CodeOnly(); 

        app.MainWindow.ShowDialog(); 
    } 
}

这样就完成只使用代码创建一个窗口的工作。这种方式并不常见,而且需要程序员写的代码很多,但是对于需要随意定制应用程序,如添加或替换控件时,这种方式要比XAML有优势的多,因为如果使用XAML文档,控件不能随意的进行修改,而作为固定不变的资源加入到程序集中。

 

WPF中仅仅使用代码就可以完成窗体的创建,但还不仅仅局限于此,还可以使用XML文件辅助完成窗体的创建。在XML文件中记录的是控件的布局情况,例如:

View Code
<?xml version="1.0" encoding="UTF-8"?> 
<DockPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> 

<Button Margin="30" Name="button1">Please click me.</Button> 

</DockPanel>

在类文件中,将控件定义的部分改成读取XML文件中的内容就可以了,类的内容如下:

View Code
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Markup; 
using System.IO;

namespace LoadAndCompileXAML 
{ 
    class CodeAndXml:Window 
    { 
        private Button button1;

        public CodeAndXml() 
        { 
            InitializeComponent(); 
        }

        private void InitializeComponent() 
        { 
            // Configure the form. 
            this.Width = this.Height = 285; 
            this.Left = this.Top = 100; 
            this.Title = "Dynamically Loaded XAML";

            // Get the XML content from an external file. 
            FileStream s = new FileStream("XMLFile1.xml", FileMode.Open);    
            DependencyObject rootElement = (DependencyObject)XamlReader.Load(s); 
            this.Content = rootElement;

            // Find the control with the appropriate name. 
            button1 = (Button)LogicalTreeHelper.FindLogicalNode(rootElement, "button1");

            // Wire up the event handler 
            button1.Click += button1_Click; 
        }

        private void button1_Click(object sender, RoutedEventArgs e) 
        { 
            button1.Content = "Thank you."; 
        } 
    } 
} 

这样同样可以完成创建窗体的任务。这是WPF中比较有趣的地方,而一般把XML文件称为未编译的XAML,通过XamlReader类对文件进行解析。但是如果页面比较复杂的话,时间消耗会比较大。

转载于:https://www.cnblogs.com/delakubi/archive/2013/03/11/2954040.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值