ぴーさんログ

だいたいXamarin.Formsのブログ

Xamarin.Forms CSS Support

Xamarin.Forms 3.0からCSS Supportが追加されます。(ASP .NET辺りの人たちにリーチしていく狙いらしい?)

一部制限はあるものの大体の機能がそのまま使えるようです、よってこの記事ではXamarin.Forms固有の事情を中心に説明します。 詳しく知りたい人は元のPull Requestを読んでください。

セレクタ関係

要素の指定

CSSにおけるHTML要素名の指定はC#クラス名の指定に置き換えられます。大文字小文字は無視されます。

/* CSS */
boxview {
    background-color: pink;
}

BoxViewクラスの背景色がピンクになります。

StyleClass

CSSにおけるclass属性にはStyleClassプロパティが対応します。(代わりにclassプロパティでも良いです)

/* CSS */
.centerelement {
    background-color: red;
}
<!-- XAML -->
<StackLayout>
    <BoxView />
    <BoxView StyleClass="centerelement" />
    <BoxView />
</StackLayout>

StyleId

CSSにおけるid属性にはStyleIdプロパティが対応します。

/* CSS */
#speciallabel {
    height: 100;
    width: 100;
    background-color: blue;
}
<!-- XAML -->
<Label Text="I'm special!" StyleId="speciallabel" />

Xamarin.Forms固有のセレクタ

要素名(C#クラス名)の先頭に^を付けるとそのクラス、およびその派生クラスへの指定となります。

/* CSS */
^contentpage {
    padding: 20;
    background-color: orange;
}

この場合、ContentPageクラスとその派生クラスへの指定となります。通常Xamarin.Formsの各画面はContentPageの派生クラスとして作るため、このようにすれば汎用的なスタイルしてができます。

スタイルシートの読み込み方

XAML

ResourcesプロパティにStyleSheet要素を追加すると、そのViewと子要素にスタイルシートが適用されます。

<ContentPage x:Class="CssSample.CssSamplePage">
    <ContentPage.Resources>
        <StyleSheet Source="/CSS/style.css" />
    </ContentPage.Resources>
</ContentPage>

ファイルからスタイルシートを読み込む場合、StyleSheet要素のSourceにCSSファイルのパスを記述します。このCSSファイルはEmbeddedResourceにする必要があります。 Sourceに指定するUriにはそのコントロールからの相対パス、または/で始まるプロジェクトルートからの絶対パスが使用できます。

f:id:ticktack623:20180319122000p:plain

この画像の場合では../CSS/style.cssまたは/CSS/style.cssが有効となります。

<ContentPage x:Class="CssSample.CssSamplePage">
    <ContentPage.Resources>
        <StyleSheet>
<![CDATA[
^contentpage {
    padding: 20;
    background-color: orange;
}

stacklayout > boxview {
    margin: 3;
    background-color: pink;
}
]]>
        </StyleSheet>
    </ContentPage.Resources>
</ContentPage>

CDATAセクションを使ってXAML内に記述することもできます。

C#

Xamarin.Forms.StyleSheets.StyleSheet.FromAssemblyResource()を使うとEmbeddedResourceからCSSファイルを読み込めます。

StyleSheet styleSheet = StyleSheet.FromAssemblyResource(this.GetType().GetTypeInfo().Assembly, "CssSample.CSS.style.css");
Resources.Add(styleSheet);

StyleSheet.FromReader()でTextReaderから読み込むことも可能。

using (var reader = new StringReader(cssString))
    myPage.Resources.Add(StyleSheet.FromReader(reader));

CSSとFlexLayout

以前に紹介したFlexLayoutを使うとCSSでもレイアウト指定ができます。

/* CSS */
.section-title {
    color: #778;
    font-style: bold;
    font-size: 20;
    margin: 6 0 0 6;
}
.grid {
    flex-wrap: wrap;
    flex-direction: row;
    align-items: stretch;
    height: 180;    
}
.grid-cell {
    flex-grow: 0;
    background-color: #eed;
    text-align: center;
    font-size: small;
    color: #556;
}
.full {
    flex-basis: 100%;
}
.half {
    flex-basis: 50%;
    background-color: cornflowerblue;
}
.third {
    flex-basis: 33.33%;
    background-color: pink;
}
.fourth {
    flex-basis: 25%;
    background-color: lightblue;
}
.auto {
    flex-grow: 1;
    background-color: coral;

}
<!-- XAML -->
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CssSample.FlexCssSamplePage">

    <ContentPage.Resources>
        <StyleSheet Source="../CSS/flexstyle.css" />
    </ContentPage.Resources>
    
    <ScrollView>
        <StackLayout>
            <Label Text="Basic Grids" StyleClass="section-title" />
            <FlexLayout StyleClass="grid">
                <Label StyleClass="grid-cell, full" Text="full" />
                <Label StyleClass="grid-cell, half" Text="1/2" />
                <Label StyleClass="grid-cell, half" Text="1/2" />
                <Label StyleClass="grid-cell, fourth" Text="1/4" />
                <Label StyleClass="grid-cell, half" Text="1/2" />
                <Label StyleClass="grid-cell, fourth" Text="1/4" />
                <Label StyleClass="grid-cell, third" Text="1/3" />
                <Label StyleClass="grid-cell, third" Text="1/3" />
                <Label StyleClass="grid-cell, third" Text="1/3" />
                <Label StyleClass="grid-cell, fourth" Text="1/4" />
                <Label StyleClass="grid-cell, fourth" Text="1/4" />
                <Label StyleClass="grid-cell, fourth" Text="1/4" />
                <Label StyleClass="grid-cell, fourth" Text="1/4" />
                <Label StyleClass="grid-cell, fourth" Text="1/4" />
                <Label StyleClass="grid-cell, third" Text="1/3" />
                <Label StyleClass="grid-cell, auto" Text="left-orver" />
            </FlexLayout>
        </StackLayout>
    </ScrollView>
</ContentPage>

上のスタイルシートとXAMLでこんなレイアウトが組めます。

f:id:ticktack623:20180319122730j:plain:w350