原文地址:框架
系列地址:http://channel9.msdn.com/Series/Windows-Phone-8-Development-for-Absolute-Beginners佈局
源代碼: http://aka.ms/absbeginnerdevwp8
PDF版本: http://aka.ms/absbeginnerdevwp8pdf學習
我將在本課中討論佈局,換句話說如何在應用程序的用戶界面上定位或者排列控件。spa
本課的計劃是:3d
缺省的Windows Phone頁面模板建立了一個稱爲"ContentPanel"的<Grid>元素。視頻
該Grid元素用於其餘控件的佈局。它容許您定義行和列,而後每一個控件能夠請求被放置在哪一行及哪一列中。對象
缺省的Windows Phone頁面模板建立了一個稱爲"ContentPanel"的<Grid>元素。blog
在默認的MainPage.xaml頁面模板中,在開始和結束標記<Grid></Grid>之間,Grid顯示爲空,它彷佛沒有行或列的定義。然而即便他們未被顯式定義,默認狀況下始終有一個行定義和列定義。他們佔據全部可用的垂直和水平空間以表明Grid中一個大的「單元」。任何放置在開始和結束<Grid></Grid>元素之間的項目被認爲位於這個隱式的「單元」之中。生命週期
"LayoutRoot" 網格是一個定義了行的Grid。該Grid定義了兩行:
請注意含有項目和頁面標題的StackPanel將本身放置在第一行中,該StackPanel有一個稱爲Grid.Row=」0」的屬性。您使用從零開始的編號方案引用行和列。
注意經過設置屬性Grid.Row=」1」,內容面板網格 (ContentPanel Grid)將本身放置在第二行。
第一行將高度設置爲」自動(Auto)」。第二行(行1)設置爲"*"。有三種語法用來幫助設置行和列的大小。對於XAML佈局,高度和寬度是相對的,並受許多因素的影響。佈局引擎考慮全部這些因素以肯定在頁面上項目的實際位置。
例如,「自動」表示該行的高度足以容納放置在其中的全部控件。若是最高的控件高度是150像素,那麼這就是該行的實際高度。若是它只有100像素,那麼那就是該行的高度。所以「自動」表示高度是相對行內部的控件。
星號稱爲「比例縮放」,它表示該行的高度應該佔據全部其他可用的高度。
這裏是另外一種使用「比例縮放」的簡單示例。我建立了一個項目,在內容面板中有針對三行的定義。請注意每一行的高度:
在星號前加上數字的含義是 「對於全部可用的空間,給我餘下的1份、2份或3份」。由於全部這些行加起來的總和是6,每一個1*至關於可用高度的1/6。所以3*將得到可用高度的一半,如本示例輸出所示:
除了自動和比例縮放,您還能夠經過像素指定寬度和高度(以及邊距)。事實上,當僅給出數字時,它表示像素的值。一般在佈局中使用精確的像素並非個好主意,由於即使是Windows Phone的屏幕也可能有不一樣的尺寸。相反,對於佈局最好使用像自動和比例縮放這樣的相對值。
在本示例中(以及原來的PetSounds示例)須要注意的一件事是除非另有指定,控件的寬度和高度都假定爲100%。這就是爲何矩形佔據整個「單元格」的緣由。這就是爲何按鈕首先佔據整個內容面板網格,以及爲何我要指定按鈕爲200 x200像素的緣由。
我還想指出的是Grid能夠包含一組有關列的定義(ColumnDefinitions),您能夠在我建立的名稱爲GridsRowsAndColumns的應用程序中找到它們。這裏咱們有了一個3 x 3的網格:
結果是一個簡單的網格,而且在每一個「單元格」中含有一個數字。
對於本示例我但願您注意到的另外一件事情是當未指定Grid.Row 或Grid.Column時,它將位於第一行(行0)或第一列(列0)。依靠默認設置可讓您的代碼更簡潔。
這裏有另外一個稱爲AlignmentAndMargins的示例應用程序。XAML以下所示:
產生這樣的結果:
若是您盯着它看一下子,示例的大部份內容是顯而易見的,可是有幾個與對齊和邊距有關的細微區別。首先,它指出VerticalAlignment和HorizontalAlignment是如何工做的(即便在給定Grid的一個單元格中,對於StackPanel一樣適用)。___Alignment屬性將控件拉到它們的邊界。相反,邊界屬性將控件推離它們的邊界。第二個須要觀察的地方是定義邊距的奇怪方式:一系列由逗號分隔的數字。這個約定從級聯樣式表借用而來。這些數字表明從左側開始順時針方向的邊距像素值。所以,
Margin="10,20,30,40"
表示距左邊界10個像素,頂部邊界20個像素,右邊界30個像素,底部邊界40個像素。在這種狀況下,邊界針對一個單獨的Grid單元格。(由於內容面板沒有定義任何其餘的行定義RowDefinitions和列定義ColumnDefinitions)
剛纔我說過使用自動和比例縮放(*)等相對大小來定義高度和寬度一般更好。那麼爲何邊距要使用像素來定義?邊距用精確的像素表示是由於它們一般只是提供兩個使用相對值對象之間的間距和填充的小數值,所以邊距能夠是一個固定值而不影響總體頁面的佈局。
StackPanel是佈局的另外一種形式。它以從上到下流動的方式排列控件。
在PetSounds項目中,咱們定義瞭如下StackPanel,它用於在MainPage.xaml的頂部建立應用程序標題和頁面標題。
兩個TextBlock元素佔據父元素(LayoutRoot Grid)的整個水平寬度,所以它們被以垂直方式堆疊。讓咱們將ContentPanel:
從Grid轉換爲StackPanel:
起初這種轉換隻將Meow按鈕垂直向下移動:
可是若是將Width和HorizontalAlignment屬性從Quack按鈕刪除(我還刪除了Button.Background屬性):
而且註釋掉Meow按鈕的Width 和HorizontalAlignment屬性,而且在MainPage()構造函數中註釋掉Margin:
而後您能夠看到兩個按鈕將以垂直方式在StackPanel中堆疊:
因此正如您所看到的,經過四件事情的聯合使用,您能夠實現任意想象的佈局
這就是XAML佈局的簡單介紹。讓咱們轉到有關事件的介紹。
若是您在Channel9觀看了C#基礎系列(C# Fundamentals series),在最後的視頻中咱們討論了事件。在Windows Phone API中,頁面和控件在其生命週期的關鍵時刻或與終端用戶交互過程當中引起事件。在本系列中咱們已經將PlayAudioButton的Click事件「鏈接」到一個稱爲「事件處理程序」的方法。當使用術語「事件處理程序」時,它指的是與事件關聯的方法。我使用術語「鏈接」的意思是事件被綁定到特定的事件處理程序方法。一些事件能夠被用戶觸發,好比按鈕控件的Click事件,其餘事件在事件的生存期內發生,例如Loaded事件在給定的頁面或控件對象被手機API運行時引擎實例化後發生。
有兩種將頁面或控件「鏈接」到事件處理程序的方法。第一種是使用XAML的屬性語法。咱們已經在PlayAudioButton示例中作過了:
若是您回想一下,咱們輸入:
Click="
而且在咱們輸入結束雙引號以前,智能感知詢問咱們是否須要選擇或建立一個事件處理程序。咱們告訴它須要以建立一個新的事件處理程序,Visual Studio將使用以下命名約定命名事件處理程序:
NameOfElement_EventName
因此在咱們的例子中,事件處理程序的名稱是:
PlayAudioButton_Click
Visual Studio同時在XAML頁面的代碼隱藏文件中建立了一個方法存根,在本例中代碼隱藏文件是MainPage.xaml.cs。請記住這就是Visual Studio自動化。當智能感知第一次出現時,咱們能夠敲鍵盤上的escape鍵並手工輸入代碼。
關聯事件與事件處理程序的第二中方法是使用Visual Studio中的屬性窗口。
(1)首先您必須確認已經經過將鼠標放置在某個元素上以選擇要編輯的控件。元素的名稱將出如今頂部的名稱字段,這使您知道設置的對象。也就是說您所作的任何設置將針對PlayAudioButton,而不是頁面上的另外一個控件。
(2)單擊閃電圖標。這將切換到一個屬性列表,在屬性窗口中能夠更改該控件能夠處理的事件。
(3)雙擊某個特定的文本框以建立控件的事件和事件處理程序之間的關聯。雙擊將自動命名事件併爲您在代碼隱藏文件中建立一個方法存根。
第三種技術(咱們將在本系列中使用數次)是在C#代碼中鏈接事件處理程序。見下面示例中的第35行:
+=運算符在其餘上下文中表示「增長並設置」,所以:
x += 1;
等同於
x = x + 1;
在某種意義上,這裏也是如此。咱們須要「添加並設置」Click事件到另外一個事件處理程序方法。是的,myButton的Click事件能夠被設置爲觸發多個事件處理程序的執行。這裏咱們說:「當Click事件被觸發時,將PlayAudioButton_Click事件處理程序添加到應該被執行的事件處理程序的列表。」一個Click事件能夠觸發一個或更多方法的執行。在咱們的應用程序中只有一個事件處理程序 PlayAudioButton_Click將被執行。
您可能想知道爲何那行代碼不是這樣:
myButton.Click += PlayAudioButton_Click();
請注意_Click後面的括號。回憶一下C# Fundamentals系列,()表明方法調用運算符。換句話說,當咱們使用()時,咱們告訴運行時當即執行那行代碼中的方法。那不是咱們想要的,咱們僅僅須要關聯或指向PlayAudioButton_Click方法。
有關事件處理程序的另外一個有趣的注意事項:當我在35行添加了以上代碼後,如今咱們有兩個事件同時指向同一個事件處理程序方法PlayAudioButton_Click。這是徹底合法的。那麼咱們如何肯定是哪一個按鈕觸發了方法的執行?
若是您看一下PlayAudioButton_Click方法的定義:
private void PlayAudioButton_Click(object sender, RoutedEventArgs e)
{
}
Windows Phone運行時將sender(發送者)做爲輸入參數傳遞。由於咱們能夠將該事件關聯到任意控件,而且sender的類型是Object(.Net框架中幾乎全部的數據類型最終都從Object類型派生),因此咱們須要作的第一件事情是進行一些檢查以肯定實際的數據類型(你是一個按鈕控件嗎?你是一個正方形控件嗎?),而後將Object強制轉換爲特定的數據類型。例如,一旦咱們將Object強制轉換爲Button,那麼咱們就能夠訪問Button的屬性了。
上述代碼片斷中方法的簽名是Windows Phone API中的典型用法。除了輸入參數sender,還有RoutedEventArgs參數, 它用於傳遞事件的額外信息。您將會看到如何在高級場景中使用它們,可是本系列中不會對其進行討論。
綜上所述,本課的重點是如何控制頁面和控件的佈局。對於Grid佈局,咱們學習了使用自動縮放、比例縮放和像素縮放來定義行和列的高度和寬度的不一樣方法。咱們討論了垂直對齊和水平對齊如何將控件拉到邊界,而邊距如何將控件推離邊界。而後咱們討論了將事件鏈接到事件處理程序的不一樣方法以及事件處理程序方法的輸入參數。