WPF -- 關於XAML語言解析處理及XAML引用
阿新 • • 發佈:2018-12-22
首先我們在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 這個類
所以最後有兩個類
-----------------------------------------------------------------------------------------