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

首先我们在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写为   

默认引用进来的两个名称空间格外重要,它们对应的程序集和 .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)语句删掉

        <Windowx: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
        {
            /// 
            /// MainWindow.xaml 的交互逻辑
            /// 
            public partial class MainWindow : Window
            {
                public MainWindow()
                {
                    //InitializeComponent();去掉这句
                }
            }
        }
    程序仍然可以运行(说明只要MainWindow.xaml 文件能够正确解析成一个窗体, 程序就可以正常运行)

(二)

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

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

WPF -- 关于XAML语言解析处理及XAML引用_第1张图片
编译后生成的 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
        {
            /// 
            /// MainWindow.xaml 的交互逻辑
            /// 
            public partial class MainWindow : Window
            {
                public MainWindow()
                {
                    InitializeComponent();
                }

                public void test() { 

                }
            }

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

WPF -- 关于XAML语言解析处理及XAML引用_第2张图片
我们发现里边有 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 控件

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

WPF -- 关于XAML语言解析处理及XAML引用_第3张图片

    图中我们看到 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 这个类
    所以最后有两个类
    -----------------------------------------------------------------------------------------

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

你可能感兴趣的:(c#,visual,studio,xaml,wpf,c#)