學習目標
- XAML 與 code 的差異
- 屬性標籤(Property-element syntax)
- OnPlatform in XAML
- 可省略的 Content property
XAML 是微軟拿來設計 Windows Phone 前端用,一種衍生自 XML 的標籤式語法。
最早出現於一般桌面 windows 應用程式~ 感謝 布陋閣 指證。
標籤式語法的好處就是關注點分離 (Separation of concerns,SOC):
將邏輯從前端分離出來,可以讓前端設計師和程式設計師專注於他們要做的事情上 (幫台灣的全端工程師QQ)。
另一個好處是較好維護,畢竟 Visual Elements 是以巢狀的方式去堆疊,而標籤語法維護巢狀時是相對容易的。
底下先來看 C# 改寫成 XAML 的例子,
這是一個包含許多屬性的 Label:
當我們改用 XAML 會變成:
上面範例可以注意到,FontSize 在 XAML 裡只要設定屬性值為 "Large",而在 C# 要用 Device.GetNamedSize() 方法才能取得並設定字體大小。
屬性標籤 (Property-element syntax)
C# - 將 Label 放在 Frame 內如下:
改成 XAML:
這種巢狀屬性的寫法都稱作 Property-element,所有的物件屬性都能寫成 property element。
例如:
或想將 LayoutOptions 拉出來也可以:
但當你想將 View Element 放入另一個物件時就很好用,
例如底下將 BoxView 放入 StackLayout.Children 內:
特定平台 (OnPlatform)
早在第二章處理 Padding 時,c# 就能針對不同平台來給予不同的值:
這東西也能轉成 XAML 的寫法如下:
可被省略的 Content property
先看一下這支程式 (很醜):
在 XAML 內其實可以把 ConetnPage.Content 或是 StackLayout.Children 或是 Frame.Content 這些標籤全部省略 (好看且更直覺):
文字在 XAML 內的特性
若要在 Label 內放入文字,最簡單的做法就是放到 Text 屬性內:
也可以把 Text 屬性拆出來:
Label.Text 是 Content Property,因此可省略:
另一個好處是較好維護,畢竟 Visual Elements 是以巢狀的方式去堆疊,而標籤語法維護巢狀時是相對容易的。
不過,XAML 有許多無法辦到的事情,例如迴圈、流程控制…等邏輯控制。
另外,Visual Studio 還沒支援拖曳物件設計前端 (或許未來吧?),截至目前還是直接寫 code。
底下先來看 C# 改寫成 XAML 的例子,
這是一個包含許多屬性的 Label:
new Label { Text = "Hello from Code!", IsVisible = true, Opacity = 0.75, HorizontalTextAlignment = TextAlignment.Center, VerticalOptions = LayoutOptions.CenterAndExpand, TextColor = Color.Blue, BackgroundColor = Color.FromRgb(255, 128, 128), FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)), FontAttributes = FontAttributes.Bold | FontAttributes.Italic };
當我們改用 XAML 會變成:
<Label Text="Hello from XAML!" IsVisible="True" Opacity="0.75" HorizontalTextAlignment="Center" VerticalOptions="CenterAndExpand" TextColor="Blue" BackgroundColor="#FF8080" FontSize="Large" FontAttributes="Bold,Italic" />
上面範例可以注意到,FontSize 在 XAML 裡只要設定屬性值為 "Large",而在 C# 要用 Device.GetNamedSize() 方法才能取得並設定字體大小。
XAML 讓程式碼看起來更簡潔了!
屬性標籤 (Property-element syntax)
C# - 將 Label 放在 Frame 內如下:
new Frame { OutlineColor = Color.Accent, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center, Content = new Label { Text = "Greetings, Xamarin.Forms!" } };
改成 XAML:
<Frame OutlineColor="Accent" HorizontalOptions="Center" VerticalOptions="Center"> <Frame.Content> <Label Text="Greetings, Xamarin.Forms!" /> </Frame.Content> </Frame>要注意的是 Frame 內使用了一個 Frame.Content 標籤,並把 Label 標籤包在 Frame.Content 內。
這種巢狀屬性的寫法都稱作 Property-element,所有的物件屬性都能寫成 property element。
例如:
<Frame HorizontalOptions="Center"> <Frame.VerticalOptions> Center </Frame.VerticalOptions> <Frame.OutlineColor> Accent </Frame.OutlineColor> <Frame.Content> <Label> <Label.Text> Greetings, Xamarin.Forms! </Label.Text> </Label> </Frame.Content> </Frame>
或想將 LayoutOptions 拉出來也可以:
<Frame> <Frame.HorizontalOptions> <LayoutOptions> <LayoutOptions.Alignment> Center </LayoutOptions.Alignment> <LayoutOptions.Expands> False </LayoutOptions.Expands> </LayoutOptions> </Frame.HorizontalOptions> … </Frame>當然我們沒必要這樣寫造成世界大亂...
但當你想將 View Element 放入另一個物件時就很好用,
例如底下將 BoxView 放入 StackLayout.Children 內:
<StackLayout> <StackLayout.Children> <StackLayout Orientation="Horizontal"> <StackLayout.Children> <BoxView Color="Red" /> <Label Text="Red" VerticalOptions="Center" /> </StackLayout.Children> </StackLayout> <StackLayout Orientation="Horizontal"> <StackLayout.Children> <BoxView Color="Green" /> <Label Text="Green" VerticalOptions="Center" /> </StackLayout.Children> </StackLayout> <StackLayout Orientation="Horizontal"> <StackLayout.Children> <BoxView Color="Blue" /> <Label Text="Blue" VerticalOptions="Center" /> </StackLayout.Children> </StackLayout> </StackLayout.Children> </StackLayout>
特定平台 (OnPlatform)
早在第二章處理 Padding 時,c# 就能針對不同平台來給予不同的值:
public partial class ScaryColorListPage : ContentPage { public ScaryColorListPage() { Padding = Device.OnPlatform(new Thickness(0, 20, 0, 0), new Thickness(0), new Thickness(0)); InitializeComponent(); } }
這東西也能轉成 XAML 的寫法如下:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="ScaryColorList.ScaryColorListPage"> <ContentPage.Padding> <OnPlatform x:TypeArguments="Thickness" iOS="0, 20, 0, 0" /> </ContentPage.Padding> <ContentPage.Content> … </ContentPage.Content> </ContentPage>
可被省略的 Content property
先看一下這支程式 (很醜):
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="ScaryColorList.ScaryColorListPage"> <ContentPage.Content> <StackLayout> <StackLayout.Children> <Frame OutlineColor="Accent"> <Frame.Content> <StackLayout Orientation="Horizontal"> <StackLayout.Children> <BoxView Color="Red" /> <Label Text="Red" VerticalOptions="Center" /> </StackLayout.Children> </StackLayout> </Frame.Content> </Frame> <Frame OutlineColor="Accent"> <Frame.Content> <StackLayout Orientation="Horizontal"> <StackLayout.Children> <BoxView Color="Green" /> <Label Text="Green" VerticalOptions="Center" /> </StackLayout.Children> </StackLayout> </Frame.Content> </Frame> <Frame OutlineColor="Accent"> <Frame.Content> <StackLayout Orientation="Horizontal"> <StackLayout.Children> <BoxView Color="Blue" /> <Label Text="Blue" VerticalOptions="Center" /> </StackLayout.Children> </StackLayout> </Frame.Content> </Frame> </StackLayout.Children> </StackLayout> </ContentPage.Content> </ContentPage>
在 XAML 內其實可以把 ConetnPage.Content 或是 StackLayout.Children 或是 Frame.Content 這些標籤全部省略 (好看且更直覺):
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="ScaryColorList.ScaryColorListPage"> <ContentPage.Padding> <OnPlatform x:TypeArguments="Thickness" iOS="0, 20, 0, 0" /> </ContentPage.Padding> <StackLayout> <Frame OutlineColor="Accent"> <StackLayout Orientation="Horizontal"> <BoxView Color="Red" /> <Label Text="Red" VerticalOptions="Center" /> </StackLayout> </Frame> <Frame OutlineColor="Accent"> <StackLayout Orientation="Horizontal"> <BoxView Color="Green" /> <Label Text="Green" VerticalOptions="Center" /> </StackLayout> </Frame> <Frame OutlineColor="Accent"> <StackLayout Orientation="Horizontal"> <BoxView Color="Blue" /> <Label Text="Blue" VerticalOptions="Center" /> </StackLayout> </Frame> </StackLayout> </ContentPage>
這些屬性標籤通稱 Content property,在 XAML 內皆可省略。
文字在 XAML 內的特性
若要在 Label 內放入文字,最簡單的做法就是放到 Text 屬性內:
<Label VerticalOptions="CenterAndExpand" Text="Single lines of text are easy." />
也可以把 Text 屬性拆出來:
<Label VerticalOptions="CenterAndExpand"> <Label.Text> Text can also be content of the Text property. </Label.Text> </Label>
Label.Text 是 Content Property,因此可省略:
<Label VerticalOptions="CenterAndExpand"> Text can also be content of the Text property. </Label>
當我們放入多行文字時,會因為放置在屬性內或是內容內而有不同的特性,
屬性內:
<Label VerticalOptions="CenterAndExpand" Text= "Perhaps the best way to define a paragraph of uniformly formatted text is by setting the Text property as an attribute and left justifying the block of text in the XAML file. End-of-line characters are converted to a space character." />
內容內:
<Label VerticalOptions="CenterAndExpand"> Text as content has the curse Of breaks at each line's close. That's a format great for verse But not the best for prose. </Label>
結果:
可以發現,若是把文字放在 Label 的屬性內,換行會被單格空白取代掉。
而若是把文字放在 Label 的內容內,會保留文字內的空白和換行。
還記得 Label 內有個 Span 屬性,能在同一 Label 內給予不同段落文字的設定,當然也能寫成 XAML 如下:
<Label VerticalOptions="CenterAndExpand"> <Label.FormattedText> <FormattedString> <Span Text="A single line with " /> <Span Text="bold" FontAttributes="Bold" /> <Span Text=" and " /> <Span Text="italic" FontAttributes="Italic" /> <Span Text=" and " /> <Span Text="large" FontSize="Large" /> <Span Text=" text." /> </FormattedString> </Label.FormattedText> </Label>
看到這句真是 中肯(幫台灣的全端工程師QQ) QQ
回覆刪除真的QQ,找到肝苦人
刪除XAML 最早出現時是微軟拿來設計 Windows Phone 前端用,一種衍生自 XML 的標籤式語法。
回覆刪除XAML 在古早弄一般桌面 windows 應用程式就在用了,那時候連網站開發的 "前端" "後端" 名詞都還沒出現
https://msdn.microsoft.com/zh-tw/library/mt149842(v=vs.110).aspx
感謝指證和補充喔~ 修正一下內容~
刪除罗根你好,我想请问一下有关文字上下间距的问题。一段文字上下的间距总是显示的特别拥挤,我想调整上下间距使其显得更加美观,请问该怎么处理?谢谢。
回覆刪除http://www.loganedge.tw/2017/08/xamarinforms-linespacinglabel-label.html
刪除直接幫你做了篇教學喔!
試試看,有問題再來一起討論!