關於 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.cs、Form1.Designer.cs和Program.cs三個檔案,下面我用Visio圖表示一下執行流程
也就是說,Form1.cs和Form1.Designer.cs最終在編譯階段形成了一個型別,所有的控制元件的定義和初始化(大多是由於開發者的拖拽和屬性編輯操作產生)全部在Form1.Designer.cs這個部分類中完成,程式碼我就不用貼出來了。我們在開發的時候只需要關心如何在Form1.cs檔案中操作部分類中定義的控制元件成員和編寫一些邏輯程式碼,從而減少開發者的編碼量。
說白了,也就是大家常說的前臺UI(Form1.Designer.cs)和後臺程式碼(Form1.cs)是部分類的關係,通過partial關鍵字實現。
Web Forms
再來看看Web Form中又是怎樣的一種形式:
這裡我們主要是看看WebForm1.aspx、WebForm1.aspx.cs和WebForm1.aspx.designer.cs這三個檔案的關係:
我們都應該知道WebForm1.aspx檔案最終也是編譯成為一個類存放於一個臨時的程式集,對於這個型別來講,它派生自WebForm1.aspx.cs檔案中定義的類,也就是說前臺UI(WebForm1.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.xaml和MainPage.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.cs和MainPage.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類,類理解起來就是同一類事物,具有同樣的特性,就如同我們常說的人類,鳥類,這樣具有相同特性和行為的一類事物的統稱,在程式設計中這種特性我們可以把它用一些方法功能來表示,例如程式:
揭祕Javascript中prototype與__proto__的關係
prototype與 __ proto__ 都是在這個過程中催生的產物,我們一會兒馬上討論,在這之...做物件即可,那javascript種究竟是通過什麼來明確繼承關係的呢。 一、建構函式: 建構函式:通過new關鍵字可以用來建立特定型別的物件的函式。比如像Object和Array,兩者屬
js中函式與物件的關係
結論:物件是由函式建立的 物件fn1由Fn函式建立 function Fn() { this.name='樑志勇'; } var fn1 = new Fn(); var obj = new Object();
關於Maven resource配製中include與exclude的關係
<include>與<exclude>是用來圈定和排除某一檔案目錄下的檔案是否是工程資源的。如果<include>與<exclude>劃定的範圍存在衝突時,以<exclude>劃定的範圍為準。大多數情況下,人們使用&l
敏捷開發之Scrum掃盲,及敏捷開發中XP與SCRUM的區別
現在敏捷開發是越來越火了,人人都在談敏捷,人人都在學習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開發中 new與alloc/init的區別 及 [NSArray array] 和 [[NSArray alloc]init] 及 self. 和 _ 的區別
專案過程中,想到這幾個概念的區別有些模糊,於是縱觀各種資料,來篇博文為自己記錄下,也為小夥伴們說說我的理解。 [className new] 和 [[className alloc] init] 的區別 1.在實際開發中很少會用到new,一般建立物件咱們看到的全
java中類與類的關係以及UML類圖
類圖主要是用來顯示系統中的類、介面以及它們之間的靜態結構和關係的一種靜態模型。 類圖的3個基本元件:類名、屬性、方法。 關係 內容 is-a 繼承 實現 us
兩張圖看懂Android開發中MVC與MVP的區別
看了很多文章,沒有很好的文章能簡明扼要的說清楚Android開發中MVC和MVP的區別。MVC很早就出來了,之前廣泛用於JavaWeb開發中,MVC也可以用來開發Android,但是有些水土不服! 1、MVC結構示意圖 2、MVP結構示意圖
怎麼去理解JAVA中類與物件的關係
首先要明確,在現實生活中,每一個物體都有自己的基本特徵,專業一點也可以說成是屬性有些甚至還有一定的行為。例如 汽車的特徵:有車門、有輪胎、顏色各一等等,行為:有行駛,開車門,開車燈,等等。有這些屬性和行為的東西,我們就可以把它稱之為“汽車”。那麼在java語言中對現實生活中的
Web開發中PHP與JAVA對比(轉載)
在市場上的電子商務軟體基本上可歸結為兩大陣營,即PHP陣營和Java陣營。但對接觸電子商務不久的使用者來說,看到的往往只是它們的表相,只是明顯的價格差異,卻很難看出它們之間的實際差異。其實,PHP+ MySQL高效的開發、品質優良的特性,已經讓風靡大學校園的Java變的越來越難堪。而作為PHP+ My
springMVC中contextConfigLocation與DispatcherServlet的關係
<servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet
node中stream與buffer的關係
JavaScript 語言自身只有字串資料型別,沒有二進位制資料型別。 但在處理像TCP流或檔案流時,必須使用到二進位制資料。因此在 Node.js中,定義了一個 Buffer 類,該類用來建立一個專門存放二進位制資料的快取區。 所以在一個應用程式中,stream是一組有