1. 程式人生 > >關於 WP 開發中.xaml 與.xaml.cs 的關係

關於 WP 開發中.xaml 與.xaml.cs 的關係

今天我們先來看一下在WP8.1開發中最長見到的幾個檔案之間的關係。比較論證,在看這個問題之前我們簡單看看.NET平臺其他兩個不同的框架:

Windows Forms

先看看Window Forms中的情況,下圖為在VS中建立的預設Windows Forms專案結構:

 

分別回顧一下每個檔案以及它們之間的關係:

┣━ Properties------------------------------------------- 專案屬性資料夾

┣━━━━━ AssemblyInfo.cs----------------------------------- 程式集資訊宣告

┣━ App.config------------------------------------------- 應用程式配置檔案

┣━ Form1.cs--------------------------------------------- 窗體Form1 類檔案

┣━━━━━ Form1.Designer.cs--------------------------------- 窗體Form1設計 類檔案

┗━ Program.cs------------------------------------------- 程式入口類檔案

這裡我們主要關心的就是Form1.csForm1.Designer.csProgram.cs三個檔案,下面我用Visio圖表示一下執行流程

也就是說,Form1.csForm1.Designer.cs最終在編譯階段形成了一個型別,所有的控制元件的定義和初始化(大多是由於開發者的拖拽和屬性編輯操作產生)全部在Form1.Designer.cs這個部分類中完成,程式碼我就不用貼出來了。我們在開發的時候只需要關心如何在Form1.cs檔案中操作部分類中定義的控制元件成員和編寫一些邏輯程式碼,從而減少開發者的編碼量。

說白了,也就是大家常說的前臺UIForm1.Designer.cs)和後臺程式碼(Form1.cs)是部分類的關係,通過partial關鍵字實現。

Web Forms

再來看看Web Form中又是怎樣的一種形式:

這裡我們主要是看看WebForm1.aspxWebForm1.aspx.csWebForm1.aspx.designer.cs這三個檔案的關係:

我們都應該知道WebForm1.aspx檔案最終也是編譯成為一個類存放於一個臨時的程式集,對於這個型別來講,它派生自WebForm1.aspx.cs檔案中定義的類,也就是說前臺UIWebForm1.aspx)是後臺程式碼(WebForm1.aspx.cs)的子類。那麼WebForm1.aspx.designer.cs又是個啥?這裡就和WinForms一樣了,它和WebForm1.aspx.cs最終也是編譯成為一個型別,在WebForm1.aspx.designer.cs也都是定義了一些控制元件,這也是當年號稱很厲害的CodeBehind,目的是將表現和邏輯隔離,當然我們這裡不需要評價CodeBehind,本身也不在今天討論的範疇之中。

Window Phone / WPF

最後來看看WP中怎麼設計的:

 

以上是Visual Studio 2013 Update 4中建立的空白Windows Phone 8.1應用,其中有一個MainPage.xamlMainPage.xaml.cs檔案,那它兩又是什麼關係呢?難道是和Windows Forms又或是Web Forms一樣嗎?

答案自然是否定的,首先XAML檔案中寫的XAML程式碼實際上就是XML語法,官方的說法:它是一個宣告物件的語言,為我們建立物件提供便捷的一種方式。與HTML類似,特點是用來描述使用者介面UI)內容

通常我們把與xaml檔案關聯的xaml.cs檔案叫作程式碼隱藏檔案。如果你引用xaml中的任何一個事件處理程式(通過事件特性,如Button的Click事件),這裡就是我們定義這些事件處理程式的地方。

我們先看看後臺程式碼

 1 namespace Demo1
 2 {
 3     /// <summary>
 4     /// 可用於自身或導航至 Frame 內部的空白頁。
 5     /// </summary>
 6     public sealed partial class MainPage : Page
 7     {
 8         public MainPage()
 9         {
10             this.InitializeComponent();
11 
12             this.NavigationCacheMode = NavigationCacheMode.Required;
13         }
14 
15         /// <summary>
16         /// 在此頁將要在 Frame 中顯示時進行呼叫。
17         /// </summary>
18         /// <param name="e">描述如何訪問此頁的事件資料。
19         /// 此引數通常用於配置頁。</param>
20         protected override void OnNavigatedTo(NavigationEventArgs e)
21         {
22             // TODO: 準備此處顯示的頁面。
23 
24             // TODO: 如果您的應用程式包含多個頁面,請確保
25             // 通過註冊以下事件來處理硬體“後退”按鈕:
26             // Windows.Phone.UI.Input.HardwareButtons.BackPressed 事件。
27             // 如果使用由某些模板提供的 NavigationHelper,
28             // 則系統會為您處理該事件。
29         }
30 
31         private void btnHello_Click(object sender, RoutedEventArgs e)
32         {
33             txtResult.Text = "Hello World";
34             var temp = (TextBlock)base.FindName("txtResult");
35             temp.Text = "Hello World2";
36         }
37     }
38 }
MainPage.cs

對於後臺程式碼檔案中定義的類同樣也有個partial ,貌似跟Windows Phone有點類似。但是我們找了找整個解決方案並沒有發現有一個與之對應的部分類,但是根據CodeLens的提示,我們能發現確實有部分類的存在而且是兩個類檔案MainPage.g.csMainPage.g.i.cs

分別雙擊開啟這個類檔案

MainPage.g.cs

 1 namespace Demo1
 2 {
 3     partial class MainPage : global::Windows.UI.Xaml.Controls.Page, global::Windows.UI.Xaml.Markup.IComponentConnector
 4     {
 5         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
 6         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
 7 
 8         public void Connect(int connectionId, object target)
 9         {
10             switch(connectionId)
11             {
12             case 1:
13                 #line 22 "..\..\MainPage.xaml"
14                 ((global::Windows.UI.Xaml.Controls.Primitives.ButtonBase)(target)).Click += this.btnHello_Click;
15                  #line default
16                  #line hidden
17                 break;
18             }
19             this._contentLoaded = true;
20         }
21     }
22 }
MainPage.g.cs

MainPage.g.i.cs

 1 namespace Demo1
 2 {
 3     partial class MainPage : global::Windows.UI.Xaml.Controls.Page
 4     {
 5         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
 6         private global::Windows.UI.Xaml.Controls.Button btnHello;
 7         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
 8         private global::Windows.UI.Xaml.Controls.TextBlock txtResult;
 9         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
10         private bool _contentLoaded;
11  
12         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
13         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
14         public void InitializeComponent()
15         {
16             if (_contentLoaded)
17                 return;
18  
19             _contentLoaded = true;
20             global::Windows.UI.Xaml.Application.LoadComponent(this, new global::System.Uri("ms-appx:///MainPage.xaml"), global::Windows.UI.Xaml.Controls.Primitives.ComponentResourceLocation.Application);
21  
22             btnHello = (global::Windows.UI.Xaml.Controls.Button)this.FindName("btnHello");
23             txtResult = (global::Windows.UI.Xaml.Controls.TextBlock)this.FindName("txtResult");
24         }
25     }
26 }
MainPage.g.i.cs

從這兩個檔案中我們可以看到,MainPage類在這裡還定義了一些控制元件和相關的方法,並且InitializeComponent()方法裡面載入和解析了MainPage.xaml檔案MainPage.cs檔案裡面的MainPage()方面裡面呼叫的InitializeComponent()方法就是在MainPage.g.cs檔案裡面定義的。在xaml頁面中宣告的控制元件,通常會在.g.cs中生成對應控制元件的內部欄位。實際上這取決於控制元件是否有x:Name屬性,只要有這個屬性,都會自動呼叫FindName方法,用於把欄位和頁面控制元件關聯。沒有x:Name屬性,則沒有欄位,這種關聯會有一定的效能浪費,因為是在應用載入控制元件的時候,通過LoadComponents方法關聯的,而xaml也是在這個時候動態解析的。

由此我們就會萌生一個動態載入XAML的想法:

我在頁面上新增一個按鈕,當按鈕點選時執行如下程式碼:

 1 int top = 100;
 2 private void btnHello_Click(object sender, RoutedEventArgs e)
 3 {
 4     string temp = "<Button xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"  " +
 5         " Content=\"這是動態載入的按鈕\"/>";
 6     Button btnTemp = (Button)XamlReader.Load(temp);
 7     // 設定水平對其方式
 8     btnTemp.HorizontalAlignment = HorizontalAlignment.Center;
 9     // 讓Margin每次都變一下
10     btnTemp.Margin = new Thickness(0, top-=100, 0, 0);
11     // 動態設定點選事件
12     btnTemp.Click += btnHello_Click;
13     grid.Children.Add(btnTemp);
14 }
動態載入按鈕XAML

效果如下圖所示:

通過C#建立按鈕的形式:

 1 /// <summary>
 2 /// 在此頁將要在 Frame 中顯示時進行呼叫。
 3 /// </summary>
 4 /// <param name="e">描述如何訪問此頁的事件資料。
 5 /// 此引數通常用於配置頁。</param>
 6 protected override void OnNavigatedTo(NavigationEventArgs e)
 7 {
 8     // TODO: 準備此處顯示的頁面。
 9  
10     // TODO: 如果您的應用程式包含多個頁面,請確保
11     // 通過註冊以下事件來處理硬體“後退”按鈕:
12     // Windows.Phone.UI.Input.HardwareButtons.BackPressed 事件。
13     // 如果使用由某些模板提供的 NavigationHelper,
14     // 則系統會為您處理該事件。
15  
16     Button btn = new Button();
17     btn.Content = "程式碼建立的按鈕";
18     btn.Click += btnHello_Click;
19     grid.Children.Add(btn);
20 }
通過C#程式碼建立控制元件

雖然我們可以這樣建立物件,但是這種形式就喪失我們XAML建立頁面元素物件的優勢了!

總結一下:XAML只是建立物件的一種便捷方式,類似於一種“命令”的形式,跟後臺程式碼沒有關係,只是在後臺執行的時候鍵xaml檔案當做資源去載入罷了!

結合這個幾個平臺來看,認為微軟為開發者考慮的太多,有的時候反倒是形成一種“負擔”!

相關推薦

關於 WP 開發.xaml .xaml.cs關係

今天我們先來看一下在WP8.1開發中最長見到的幾個檔案之間的關係。比較論證,在看這個問題之前我們簡單看看.NET平臺其他兩個不同的框架: Windows Forms 先看看Window Forms中的情況,下圖為在VS中建立的預設Windows Forms專案結構:   分別回顧一下每個檔案以及它們之

iOS開發地圖定位

視圖 編寫 aps 簡單 -a 第三方 span spa margin   不管是QQ還是微信的移動client都少不了定位功能,之前在微信demo中沒有加入定位功能,今天就寫個定位的小demo來了解一下定位和地圖的東西。地圖和定位看上去是挺高大上一東西。其有使用方法比

C#物件的關係,以及方法申明的static修飾符

C#中,類(class)的書寫,是class 類名稱:例如class Program這就是一個Program類,類理解起來就是同一類事物,具有同樣的特性,就如同我們常說的人類,鳥類,這樣具有相同特性和行為的一類事物的統稱,在程式設計中這種特性我們可以把它用一些方法功能來表示,例如程式:

揭祕Javascriptprototype__proto__的關係

prototype與 __ proto__ 都是在這個過程中催生的產物,我們一會兒馬上討論,在這之...做物件即可,那javascript種究竟是通過什麼來明確繼承關係的呢。 一、建構函式: 建構函式:通過new關鍵字可以用來建立特定型別的物件的函式。比如像Object和Array,兩者屬

js函式物件的關係

結論:物件是由函式建立的   物件fn1由Fn函式建立 function Fn() { this.name='樑志勇'; } var fn1 = new Fn(); var obj = new Object();

關於Maven resource配製includeexclude的關係

                <include>與<exclude>是用來圈定和排除某一檔案目錄下的檔案是否是工程資源的。如果<include>與<exclude>劃定的範圍存在衝突時,以<exclude>劃定的範圍為準。大多數情況下,人們使用&l

敏捷開發之Scrum掃盲,及敏捷開發XPSCRUM的區別

現在敏捷開發是越來越火了,人人都在談敏捷,人人都在學習Scrum和XP... 為了不落後他人,於是我也開始學習Scrum,今天主要是對我最近閱讀的相關資料,根據自己的理解,用自己的話來講述Scrum中的各個環節,主要目的有兩個,一個是進行知識的總結,另外一個是覺得網上很多學習資料的講述方式讓初學者不太容易

敏捷開發軟體文件的思考

也曾嘗試過,不帶文件的“裸體”前進,可想而知,最後經常造成專案的返工,新來的人員要拼命讀以前的人留下的幾乎沒有註釋的原始碼。        後來嘗試過,制訂完善的規範,用了大量的軟體開發文件模板,可惜仍然無法減輕開發者的負擔,另一方面令人尷尬的是,情況並沒有比不帶文件好多少,

Java棧的關係

資料型別     Java虛擬機器中,資料型別可以分為兩類:基本型別和引用型別。基本型別的變數儲存原始值,即:他代表的值就是數值本身;而引用型別的變數儲存引用值。“引用值”代表了某個物件的引用,而不是物件本身,物件本身存放在這個引用值所表示的地址的位置。 基本型別包括:byte,short,int,long

Java物件的關係區別

什麼是類?類就是具備某些共同特徵的實體的集合,它是一種抽象的資料型別,它是對所具有相同特徵實體的抽象。在面向物件的程式設計語言中,類是對一類“事物”的屬性與行為的抽象。什麼是物件?物件就是一個真實世界中的實體,物件與實體是一一對應關係的,意思就是現實世界的每一個實體都是一個物

Android開發佈局元件(二)—— padding margin 的區別

在 Android開發中我們會設定某個檢視相對於別的檢視的距離,這時我們就要用到 margin 和 padding ,但是有時候很容易把這兩個屬性弄混淆,那我們就看看他們的區別。 外邊距(margin): 屬於佈局引數,決定兩個元件之間的距離。作用於多個元件之間。 內邊距(

Android開發佈局元件(一)—— 螢幕尺寸單位dp,px,sp的探究

在Android開發中,常用的尺寸單位有 dp , px , sp 。當然還有其他的單位如 pt , mm 等,不過這些都是不常用,所以我們重點來探究一下 dp , px , sp 這三個常用的單位。 px 英文 pixel 的縮寫,即畫素。無論螢幕密度為多少,一個畫素單位對應

js 的prototype 屬性和用法,外加__proto__ JavaScript__proto__prototype的關係

var ob = { };//超級簡單的空物件 alert(JSON.stringify(ob.prototype));// undefined 能夠引用prototype的東西絕對是函式,絕對是函式,絕對是函式,prototype是屬於函式的一個屬性,prototype是屬於函式的一個屬性,prototy

iOS開發 newalloc/init的區別 及 [NSArray array] 和 [[NSArray alloc]init] 及 self. 和 _ 的區別

專案過程中,想到這幾個概念的區別有些模糊,於是縱觀各種資料,來篇博文為自己記錄下,也為小夥伴們說說我的理解。 [className new] 和 [[className alloc] init] 的區別 1.在實際開發中很少會用到new,一般建立物件咱們看到的全

java類的關係以及UML類圖

類圖主要是用來顯示系統中的類、介面以及它們之間的靜態結構和關係的一種靜態模型。 類圖的3個基本元件:類名、屬性、方法。 關係 內容 is-a 繼承 實現 us

兩張圖看懂Android開發MVCMVP的區別

看了很多文章,沒有很好的文章能簡明扼要的說清楚Android開發中MVC和MVP的區別。MVC很早就出來了,之前廣泛用於JavaWeb開發中,MVC也可以用來開發Android,但是有些水土不服! 1、MVC結構示意圖 2、MVP結構示意圖

怎麼去理解JAVA物件的關係

首先要明確,在現實生活中,每一個物體都有自己的基本特徵,專業一點也可以說成是屬性有些甚至還有一定的行為。例如 汽車的特徵:有車門、有輪胎、顏色各一等等,行為:有行駛,開車門,開車燈,等等。有這些屬性和行為的東西,我們就可以把它稱之為“汽車”。那麼在java語言中對現實生活中的

Web開發PHPJAVA對比(轉載)

    在市場上的電子商務軟體基本上可歸結為兩大陣營,即PHP陣營和Java陣營。但對接觸電子商務不久的使用者來說,看到的往往只是它們的表相,只是明顯的價格差異,卻很難看出它們之間的實際差異。其實,PHP+ MySQL高效的開發、品質優良的特性,已經讓風靡大學校園的Java變的越來越難堪。而作為PHP+ My

springMVCcontextConfigLocationDispatcherServlet的關係

<servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet

nodestreambuffer的關係

JavaScript 語言自身只有字串資料型別,沒有二進位制資料型別。 但在處理像TCP流或檔案流時,必須使用到二進位制資料。因此在 Node.js中,定義了一個 Buffer 類,該類用來建立一個專門存放二進位制資料的快取區。 所以在一個應用程式中,stream是一組有