您的位置:首页 > 编程语言 > C#

WPF -- 关于XAML语言解析处理及XAML引用

2015-09-11 18:17 921 查看
首先我们在Visual Studio中建立一个WPF项目,以下是新建的WPF程序的 xaml 文件

<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
//绘制UI相关程序集  表示(Presentation)层
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
//语言解析处理程序集语言层
Title="MainWindow" Height="350" Width="525">
<Grid>

</Grid>
</Window>


XAML引用:

XAML 中引用外来程序集和其中.NET 名称空间

xmlns:c="clr-namespace:System.Windows.Controls; assembly=PresentationFramework"

-------------------------------------------------------------------------
c 是映射前缀, 可以换成其他字符串 如:"control"

因Button来自前缀 c 对应的名称空间,所以使用Button写为  <c:Button> </c:Button>

默认引用进来的两个名称空间格外重要,它们对应的程序集和 .NET 名称空间如下

-------------------------------------------------------------- http://schemas.microsoft.com/winfx/2006/xaml/presentation 对应:

*System.Windows
*System.Windows.Automarion
*System.Windows.Controls
*System.Windows.Controls.Primitives
*System.Data
*System.Windows.Documents
*System.Windows.Forms.Integration
*System.Windows.Ink
*System.Windows.Input
*System.Windows.Media
*Syatem.Windows.Media.Animation
*System.Windows.Media.Effects
*System.Windows.Media.Imaging
*System.Windows.Media.Media3D
*System.Windows.Media.TextFormatting
*System.Windows.Navigation
*System.Windows.Shapes
---------------------------------------------------------------


XAML语言解析处理:

(一)

1.首先将x:Class=”WpfApplication1.MainWindow”这条(Attribute)语句删掉

<Window (x:Class="WpfApplication1.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>
</Grid>
</Window>


2.再删掉MainWindow.xaml.cs的 InitializeComponent 方法

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 WpfApplication1
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
//InitializeComponent();去掉这句
}
}
}


程序仍然可以运行(说明只要MainWindow.xaml 文件能够正确解析成一个窗体, 程序就可以正常运行)


(二)

然后恢复 x:Class这个 Attribute(不恢复 InitializeComponent 方法的调用)
并更改为 x:Class="WpfApplication1.MainWindowABC"

程序依旧可以运行
这时我们打开IL Disassembler(中间语言反编译器)
发现项目编译生成的程序集里包含一个 MainWindowABC 的类




编译后生成的 MainWindowABC 的代码看起来大致为

using System.Windows;
using System.Windows.Controls;

class MainWindowABC : Window
{
private Grid grid;

public WindowABC()
{
grid = new Grid();
this.Content = grid;
}
}


最后,我们回到最初的代码

你会问在 XAML 里有 x:Class="WpfApplication1.MainWindow",在 MainWindow.xaml.cs 里也声明了 MainWindow 这个类,难道它们不会冲突吗?
我们发现 MainWindow 这个类在声明时使用了 partial 关键字。
使用 partial 关键字,可以把一个类分拆在多处定义,只要各部分代码不冲突即可
这样,XAML 解析成的类和 C# 文件里定义的部分就合二为一。


以上均为 《深入浅出WPF》 一书中的内容, 下方为个人的验证以及感悟

下边我们通过一个例子来证明 partial 将 XANL 解析的类和 C# 中的类合并:

下边是Main.xaml的代码 (在原始xaml文件里加一个Button控件)


<Window x:Class="WpfApplication1.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>
<Button Content="Button" Height="23" HorizontalAlignment="Left"
Margin="162,149,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
</Grid>
</Window>


下边是Main.xaml.cs的代码(我们在类MainWindow类加一个 test 方法)


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 WpfApplication1
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

public void test() {

}
}

}


编译生成
然后我们用反编译器打开发财编译生成的程序,




我们发现里边有 button1控件 和 test 方法,证明了 partial的作用

(三)

前边(二)中我们只恢复 x:Class 这个 Attribute(不恢复 InitializeComponent 方法的调用)
并更改为 x:Class="WpfApplication1.MainWindowABC"

接下来我们做的例子是 继续在上边(二)中的代码里做如下改动

1.恢复 MainWindow.xaml.cs 里 InitializeComponent 方法的调用

2.在 WpfApplication1 中新建一个 WPF 窗口页面,起名为 Window1,会生成一个Window1.xaml文件和
一个Window1.xaml.cs文件

3.将 Window1.xaml 中 x:Class 这个 Attribute 更改为 x:Class="WpfApplication1.MainWindow"

4.去掉Window1.xaml.cs 里的 InitializeComponent 方法

5.在 Mainwindow.xaml 里加入一个 Button 控件

6.在 Window1.xaml 里加入一个 Label 控件

编译运行,然后再反编译器里打开




图中我们看到 3 个类
*   WpfApplication1.MainWindow
*   WpfApplication1.MainWindowABC
*   WpfApplication1.Window1

我们看到 MainWindowABC 类里有个 Button 控件和 InitializeComponent 方法
MainWindow 类里有个 Label 控件和 InitializeComponent 方法
而Window1里什么也没有

疑问:

Label 控件是在 Window1.xaml 里添加,为什么会出现在 MainWindow类里?
看一下 Window1.xaml 里这句 x:Class="WpfApplication1.MainWindow"
这让你想到了什么吗?

感悟1:
--------------------------------------------------------------------------------------
MainWindow.xaml.cs 里 InitializeComponent 方法在调用的时候,
会在所有 XAML 解析后生成的类中寻找 MainWindow 类,
并将 XAML 解析生成的 MainWindow 类和 MainWindow.xaml.cs 生成的 MainWindow 类
合并为一
如果所有 XAML 解析后没有 MainWindow 这个类就会出错,就要去掉 InitializeComponent 方法的调用
而想要 XAML 解析生成 MainWindow 类,就需要在某个 xaml 文件里添加
x:Class="WpfApplication1.MainWindow" 才会生成相应的类
---------------------------------------------------------------------------------------

感悟2:
-----------------------------------------------------------------------------------------
在(二)中的例子里,最后生成两个类 MainWindowABC 和 MainWindow,但是App.xaml里启动项仍是
MainWindow.xaml。

将 MainWindow.xaml 解析,生成了 MainWindowABC 这个类
而 MainWindow.xaml.cs 在编译的时候生成了 MainWindow 这个类
所以最后有两个类
-----------------------------------------------------------------------------------------


以上均为个人见解,如有什么错误或者偏差的地方,希望大家可以帮忙指出,我会及时改正

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  visual studio xaml wpf c#