2018/5/11

Xamarion.Forms 3.0 Styling with CSS StyleSheet


Xamarin.Fomrs 3.0 重要更新之一
就是使用我們網頁工程師常用的 CSS 來做 App 樣式排版

其中最棒的就是支援 CSS 選擇器
大幅增加 Styling 的彈性

本教學也幫大家統整了Xamairn.Forms 目前支援的選擇器和對應樣式



Xamarin.Fomrs 3.0 出來之前,
樣式管理最多就用 Resource.MergedDictionaries,除此之外別無他法...

結果變成 Style 資料夾存在一堆 XAML 檔案...



多了 CSS 功能後,終於能把 Style 程式拆得更乾淨,管理上也更加方便


1. 新增 CSS 檔案
在專案下隨意地方新增一個 css 檔



2. 改為內嵌資源
由於 Xamrin.Fomrs 使用 css 的時機為 App Runtime 時,所以 css 檔案必須為 內嵌資源 (EmbeddedResource )

對檔案右鍵 → 屬性 → 
用 VisualStudio 2017 15.7 加入 css 後的檔案會自動改成內嵌資源


3. 開始寫 Style

不過在開始寫之前,要先了解  Xamarin.Fomrs 支援的 CSS 選擇器有哪些


顧名思義就是要 "如何選擇" 我們畫面上的元件,來套用 Style

底下列出目前 Xamarin.Fomrs 支援的選擇器
//更新至 2018/05/11
//選擇器不分大小寫

選擇器 範例 說明
.class .header 選擇屬性 StyleClass 的值為 header 的元件
#id #account 選擇 x:Name 的值為 account 的元件
* * 選擇所有元件
element stacklayout 選擇所有 StackLayout
^base ^stacklayout 選擇所有 StackLayout 和 繼承於 StackLayout 的元件
// Xamarin.Fomrs 限定
element,element stacklayout, label 選擇所有 StackLayout 和 所有 Label
element element stacklayout label 選擇 StackLayout 內所有 Label
element>element stacklayout>label 選擇父層元素為 StackLayout 的所有 Label
element +element label+entry 選擇所有排在 Label 後面的 Entry
element~element label~entry 選擇所有排在 Label 前面的 Entry

選擇器可以無限串接,例如 stacklayout > label .title 

接著在 css 內來寫一段
更改 StackLayout 內所有 Label 字顏色的程式
stacklayout label
{
    color : firebrick;
}

並在 XAML 內使用
<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Style/StyleSheet1.css" />
    </ContentPage.Resources>
        <StackLayout>
            ...
            <Label ... />
            ...
        </StackLayout>
</ContentPage>

結果:

部屬前要先建置過一次,不然 Xamarin 會找不到你新建立的 css !

能不能在 XAML 寫 css ?
可以的,用 <![CDATA[ 像這樣寫,醜醜的就是了...

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet>
            <![CDATA[
            ^contentpage {
                background-color: lightgray;
            }
            ]]>
        </StyleSheet>
    </ContentPage.Resources>
    ...
</ContentPage>


能不能在 C# 寫 css ?
也是可以的,所有 style 的東西都先經過編譯才能用,所以 c# 也有相對應的寫法
//一樣很醜

1. 讀取 Sheet 檔
public partial class MyPage : ContentPage
{
    public MyPage()
    {
        InitializeComponent();

        this.Resources.Add(StyleSheet.FromAssemblyResource(
            IntrospectionExtensions.GetTypeInfo(typeof(MyPage)).Assembly,
            "MyProject.Assets.styles.css"));
    }
}

2.直接寫 css 的話要使用 StringReader
public partial class MyPage : ContentPage
{
    public MyPage()
    {
        InitializeComponent();

        using (var reader = new StringReader("^contentpage { background-color: lightgray; }"))
        {
            this.Resources.Add(StyleSheet.FromReader(reader));
        }
    }
}



最後,整理下目前 Xamarin.Fomrs 和 css 相對應的屬性
//更新至 2018/05/11

css屬性 可用元件 範例
background-color VisualElementbackground-color: springgreen;
background-image Page background-image: bg.png;
border-color Button, Frame border-color: #9acd32;
border-width Button border-width: .5;
color Button, DatePicker, Editor,
Entry, Label, Picker,
SearchBar, TimePicker
color: rgba(255, 0, 0, 0.3);
direction VisualElement direction: rtl;
font-family Button, DatePicker, 
Editor, Entry, Label, 
Picker, SearchBar, 
TimePicker, Span
font-family: Consolas;
font-size Button, DatePicker, Editor,
Entry, Label, Picker,
SearchBar, TimePicker, Span
font-size: 12;
font-style Button, DatePicker, Editor,
Entry, Label, Picker,
SearchBar, TimePicker, Span
font-style: bold;
height VisualElement min-height: 250;
margin View margin: 6 12;
margin-left View margin-left: 3;
margin-top View margin-top: 2;
margin-right View margin-right: 1;
margin-bottom View margin-bottom: 6;
min-height VisualElement min-height: 50;
min-width VisualElement min-width: 112;
opacity VisualElement opacity: .3;
padding Layout, Page padding: 6 12 12;
padding-left Layout, Page padding-left: 3;
padding-top Layout, Page padding-top: 4;
padding-right Layout, Page padding-right: 2;
padding-bottom Layout, Page padding-bottom: 6;
text-align Entry, EntryCell, 
Label, SearchBar
text-align: right;
visibility VisualElement visibility: hidden;
width VisualElement min-width: 320;

小心 Thickness 的 Margin 和 Padding

Thickness 和 css 填入數字的順序,其位置代表的意思是不一樣的
Xamarin.Forms css
new Thickness(左, 上, 右, 下) 上, 右, 下, 左
new Thickness(水平, 垂直) 垂直, 水平




沒有留言:

張貼留言