小序:
按照慣例,我會在年底的最後一篇文章裏感謝全部幫助過個人人們。今年也不例外,只是形式簡單一些。
祝全部幫助過個人朋友、同事、學生和兄弟姐妹們——2009年身體健康、平安快樂、財源滾滾。願2009年的中國,平安祥和、遠離各類災難,你們的工資漲上去、房價降下來,金融危機早點結束。
祝個人父親母親,健康長壽!
正文:
……上文省略若干千字……
還剩下x:Class="MyFirstWpfApplication.Window1"這個Attribute。x:前綴說明這個Attribute來自於x映射的名稱空間——前面我剛剛分析過,這個名稱空間是對應XAML解析功能的。x:Class,顧名思義它與類有此關係,是何種關係呢?讓咱們作個有趣的實驗:
首先,咱們把x:Class="MyFirstWpfApplication.Window1"這個Attribute刪掉,再到Window1.xaml.cs文件裏,把InitializeComponent();這個函數調用也刪掉。編譯程序,你會發現程序仍然能夠運行。爲何呢?打開App.xaml這個文件,你能發現這樣一個Attribute——StartupUri="Window1.xaml",它是在告訴編譯器把由Window1.xaml解析後生成的窗體做爲程序啓動時的主窗體。也就是說,只要Window1.xaml文件可以被正確解析成一個窗體,程序就能夠正常運行。
而後,咱們恢復x:Class這個Attribute,更改它的值爲x:Class="MyFirstWpfApplication.WindowABC"。編譯以後,仍然能夠正確運行。這時,咱們使用IL Disassembler(中間語言反編譯器)打開項目的編譯結果,你會發如今由項目編譯生成的程序集裏包含一個名爲WindowABC的類。
這說明,x:Class這個Attribute的做用是當XAML解析器將包含它的標籤解析成C#類後,這個類的類名是什麼。這裏,咱們已經觸及到的XAML的本質。前面咱們已經看到,示例代碼的結構就是使用XAML語言直觀地告訴咱們,固然被設計的窗體是在一個<Window>裏嵌套一個<Grid>。若是使用C#來完成一樣的設計呢?顯然,咱們不可能去更改Window這個類,咱們能作的是從Window類派生出一個類來(好比叫WindowABC),再爲這個類添加一個Grid類型的字段,而後把這個字段在初始化的時候賦值給派生類的內容屬性。代碼看起來大概是這樣:
using System.Windows;
using System.Windows.Controls;
class WindowABC : Window
{
private Grid grid;
public WindowABC()
{
grid = new Grid();
this.Content = grid;
}
}
最後,讓咱們回到最初的代碼。你可能會問:在XAML裏有x:Class="MyFirstWpfApplication.Window1",在Window1.xaml.cs裏也聲明瞭Window1這個類,難道它們不會衝突嗎?仔細看看Window1.xaml.cs中Window1類的聲明就知道了——在聲明時使用了partial這個關鍵字。使用partial關鍵字,能夠把一個類分拆在多處定義,只要各部分代碼不衝突便可。顯然,由XAML解析器生成的Window1類在聲明時也使用了partial關鍵字,這樣,由XAML解析成的類和C#文件裏定義的部分就合而爲一了。正是因爲這種partial機制,咱們能夠把類的邏輯代碼留在.cs文件裏、用C#語言來實現,而把那些與聲明及佈局UI元素相關的代碼分離出去,實現UI與邏輯分離。而且,用於繪製UI的代碼(好比聲明控件類型的字段、設置它們的外觀和佈局等)也沒必要再使用C#語言——使用XAML和XAML編輯工具就能輕鬆搞定!