Стилизация Xamarin.Forms приложений с помощью каскадных таблиц стилей (CSS)

Download Sample Скачайте пример

Xamarin.Forms поддерживает стили визуальных элементов с помощью каскадных таблиц стилей (CSS).

Xamarin.Forms приложения можно стильировать с помощью CSS. Таблица стилей состоит из списка правил с каждым правилом, состоящим из одного или нескольких селекторов и блока объявления. Блок объявления состоит из списка объявлений в фигурных скобках с каждым объявлением, состоящим из свойства, двоеточия и значения. При наличии нескольких объявлений в блоке точка с запятой вставляется в качестве разделителя. В следующем примере кода показаны некоторые совместимые Xamarin.Forms CSS:

navigationpage {
    -xf-bar-background-color: lightgray;
}

^contentpage {
    background-color: lightgray;
}

#listView {
    background-color: lightgray;
}

stacklayout {
    margin: 20;
}

.mainPageTitle {
    font-style: bold;
    font-size: medium;
}

.mainPageSubtitle {
    margin-top: 15;
}

.detailPageTitle {
    font-style: bold;
    font-size: medium;
    text-align: center;
}

.detailPageSubtitle {
    text-align: center;
    font-style: italic;
}

listview image {
    height: 60;
    width: 60;
}

stacklayout>image {
    height: 200;
    width: 200;
}

В Xamarin.Formsтаблицах стилей CSS анализируются и оцениваются во время выполнения, а не во время компиляции, а таблицы стилей повторно анализируются при использовании.

Примечание.

В настоящее время все стили, которые можно использовать с помощью стилей XAML, невозможно выполнить с помощью CSS. Однако стили XAML можно использовать для дополнения CSS для свойств, которые в настоящее время не поддерживаются Xamarin.Forms. Дополнительные сведения о стилях XAML см. в руководстве по оформлению приложений Xamarin.Forms с использованием стилей XAML.

Пример MonkeyAppCSS демонстрирует использование CSS для стиля простого приложения и показан на следующих снимках экрана:

MonkeyApp Main Page with CSS styling

MonkeyApp Detail Page with CSS styling

Использование таблицы стилей

Процесс добавления таблицы стилей в решение выглядит следующим образом:

  1. Добавьте пустой CSS-файл в проект библиотеки .NET Standard.
  2. Задайте для действия сборки CSS-файла значение EmbeddedResource.

Загрузка таблицы стилей

Существует ряд подходов, которые можно использовать для загрузки таблицы стилей.

Примечание.

В настоящее время невозможно изменить таблицу стилей во время выполнения и применить новую таблицу стилей.

XAML

Таблицу стилей можно загрузить и проанализировать с StyleSheet классом ResourceDictionaryперед добавлением в :

<Application ...>
    <Application.Resources>
        <StyleSheet Source="/Assets/styles.css" />
    </Application.Resources>
</Application>

Свойство StyleSheet.Source задает таблицу стилей в виде URI относительно расположения включающего XAML-файла или относительно корневого каталога проекта, если универсальный код ресурса (URI) начинается с /.

Предупреждение

CSS-файл не будет загружаться, если его действие сборки не задано как EmbeddedResource.

Кроме того, таблицу стилей можно загрузить и проанализировать с StyleSheet классом, прежде чем добавлять его в ResourceDictionaryCDATA раздел.

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

Дополнительные сведения о словарях ресурсов см. в разделах "Словари ресурсов".

C#

В C# таблицу стилей можно загрузить из таблицы стилей StringReader и добавить в :ResourceDictionary

public partial class MyPage : ContentPage
{
    public MyPage()
    {
        InitializeComponent();

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

Аргумент StyleSheet.FromReader метода — это чтение TextReader таблицы стилей.

Выбор элементов и применение свойств

CSS использует селекторы для определения целевых элементов. Стили с селекторами сопоставления применяются последовательно в порядке определения. Стили, определенные для определенного элемента, всегда применяются последним. Дополнительные сведения о поддерживаемых селекторах см. в справочнике по селекторам.

CSS использует свойства для стиля выбранного элемента. Каждое свойство имеет набор возможных значений, а некоторые свойства могут повлиять на любой тип элемента, а другие применяются к группам элементов. Дополнительные сведения о поддерживаемых свойствах см. в справочнике по свойствам.

Дочерние таблицы стилей всегда переопределяют родительские таблицы стилей, если они задают одинаковые свойства. Поэтому при применении стилей, которые задают одни и те же свойства, следует соблюдать следующие правила приоритета:

  • Стиль, определенный в ресурсах приложения, будет перезаписан стилем, определенным в ресурсах страниц, если они задают те же свойства.
  • Стиль, определенный в ресурсах страницы, будет перезаписан стилем, определенным в ресурсах элемента управления, если они задают одинаковые свойства.
  • Стиль, определенный в ресурсах приложения, будет перезаписан стилем, определенным в ресурсах управления, если они задают одинаковые свойства.

Внимание

Переменные CSS не поддерживаются.

Выбор элементов по типу

Элементы в визуальном дереве можно выбрать по типу с нечувствительным element селектором регистра:

stacklayout {
    margin: 20;
}

Этот селектор определяет все StackLayout элементы на страницах, использующих таблицу стилей, и задает их поля на единую толщину 20.

Примечание.

element Селектор не определяет подклассы указанного типа.

Выбор элементов по базовому классу

Элементы в визуальном дереве можно выбрать базовым классом с нечувствительным ^base селектором регистра:

^contentpage {
    background-color: lightgray;
}

Этот селектор идентифицирует все ContentPage элементы, использующие таблицу стилей, и задает их цвет lightgrayфона.

Примечание.

^base Селектор относится к Xamarin.Formsспецификации CSS и не является частью спецификации CSS.

Выбор элемента по имени

Отдельные элементы в визуальном дереве можно выбрать с помощью селектора с учетом #id регистра:

#listView {
    background-color: lightgray;
}

Этот селектор определяет элемент, для свойства которого StyleId задано listViewзначение . Однако если StyleId свойство не задано, селектор будет возвращаться к использованию x:Name элемента. Таким образом, #listView в следующем примере XAML селектор будет определять ListView атрибут, для которого x:Name задано listViewзначение , и присвойте ему цвет lightgrayфона.

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Assets/styles.css" />
    </ContentPage.Resources>
    <StackLayout>
        <ListView x:Name="listView" ...>
            ...
        </ListView>
    </StackLayout>
</ContentPage>

Выбор элементов с определенным атрибутом класса

Элементы с определенным атрибутом класса можно выбрать с помощью селектора с учетом .class регистра:

.detailPageTitle {
    font-style: bold;
    font-size: medium;
    text-align: center;
}

.detailPageSubtitle {
    text-align: center;
    font-style: italic;
}

Класс CSS можно назначить элементу XAML, задав StyleClass свойству элемента имя класса CSS. Поэтому в следующем примере XAML стили, определенные классом, назначаются первомуLabel, а стили, определенные .detailPageTitle.detailPageSubtitle классом, назначаются второмуLabel.

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Assets/styles.css" />
    </ContentPage.Resources>
    <ScrollView>
        <StackLayout>
            <Label ... StyleClass="detailPageTitle" />
            <Label ... StyleClass="detailPageSubtitle"/>
            ...
        </StackLayout>
    </ScrollView>
</ContentPage>

Выбор дочерних элементов

Дочерние элементы в визуальном дереве можно выбрать с помощью нечувствительного element element селектора регистра:

listview image {
    height: 60;
    width: 60;
}

Этот селектор определяет все Image элементы, которые являются дочерними элементами ListView элементов, и задает их высоту и ширину 60. Таким образом, listview image в следующем примере XAML селектор будет определять Image дочерний ListViewобъект и задает его высоту и ширину 60.

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Assets/styles.css" />
    </ContentPage.Resources>
    <StackLayout>
        <ListView ...>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid>
                            ...
                            <Image ... />
                            ...
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

Примечание.

element element Селектор не требует, чтобы дочерний элемент был прямым дочерним элементом родительского элемента— дочерний элемент может иметь другой родительский элемент. Выбор происходит при условии, что предок является указанным первым элементом.

Выбор прямых дочерних элементов

Прямые дочерние элементы в визуальном дереве можно выбрать с помощью нечувствительного element>element селектора регистра:

stacklayout>image {
    height: 200;
    width: 200;
}

Этот селектор определяет все Image элементы, которые являются прямыми дочерними элементами StackLayout элементов, и задает их высоту и ширину 200. Таким образом, stacklayout>image в следующем примере XAML селектор будет определять Image прямой дочерний StackLayoutобъект и задает его высоту и ширину 200.

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Assets/styles.css" />
    </ContentPage.Resources>
    <ScrollView>
        <StackLayout>
            ...
            <Image ... />
            ...
        </StackLayout>
    </ScrollView>
</ContentPage>

Примечание.

element>element Селектор требует, чтобы дочерний элемент был прямым дочерним элементом родительского элемента.

Справочник по селектору

Следующие селекторы CSS поддерживаются:Xamarin.Forms

Выбор Пример Description
.class .header Выбирает все элементы со свойством StyleClass , содержащим "заголовок". Обратите внимание, что этот селектор учитывает регистр.
#id #email Выбирает все элементы с заданным StyleId значением email. Если StyleId значение не задано, откат к x:Name. При использовании XAML x:Name предпочтительнее StyleId. Обратите внимание, что этот селектор учитывает регистр.
* * Выбирает все элементы.
element label Выбирает все элементы типа Label, но не подклассы. Обратите внимание, что этот селектор не учитывает регистр.
^base ^contentpage Выбирает все элементы в ContentPage качестве базового класса, включая ContentPage себя. Обратите внимание, что этот селектор не учитывает регистр и не является частью спецификации CSS.
element,element label,button Выбирает все элементы и все ButtonLabel элементы. Обратите внимание, что этот селектор не учитывает регистр.
element element stacklayout label Выбирает все Label элементы внутри StackLayout. Обратите внимание, что этот селектор не учитывает регистр.
element>element stacklayout>label Выбирает все Label элементы с StackLayout прямым родительским элементом. Обратите внимание, что этот селектор не учитывает регистр.
element+element label+entry Выбирает все Entry элементы непосредственно после Label. Обратите внимание, что этот селектор не учитывает регистр.
element~element label~entry Выбирает все Entry элементы, предшествующие объекту Label. Обратите внимание, что этот селектор не учитывает регистр.

Стили с селекторами сопоставления применяются последовательно в порядке определения. Стили, определенные для определенного элемента, всегда применяются последним.

Совет

Селекторы можно объединить без ограничений, например StackLayout>ContentView>label.email.

В настоящее время неподдерживаемые селекторы:

  • [attribute]
  • @media и @supports
  • : и ::

Примечание.

Особенности и переопределения конкретности не поддерживаются.

Справочные данные по свойствам

Следующие свойства CSS поддерживаются Xamarin.Forms (в столбце "Значения" типы являются курсивными, а строковые литералы):gray

Свойство Применяется к Values Пример
align-content FlexLayout stretch | center | start | end | spacebetween | spacearound | spaceevenly | flex-start | flex-end | space-between | space-around | initial align-content: space-between;
align-items FlexLayout stretch | center | start | end | flex-start | flex-end | initial align-items: flex-start;
align-self VisualElement auto | stretch | center | start | end | flex-start | flex-end | initial align-self: flex-end;
background-color VisualElement color | initial background-color: springgreen;
background-image Page string | initial background-image: bg.png;
border-color Button, , FrameImageButton color | initial border-color: #9acd32;
border-radius BoxView, , ButtonFrameImageButton double | initial border-radius: 10;
border-width Button, ImageButton double | initial border-width: .5;
color ActivityIndicator, BoxView, ButtonCheckBoxDatePickerEditorEntryLabelPickerProgressBarSearchBarSwitchTimePicker color | initial color: rgba(255, 0, 0, 0.3);
column-gap Grid double | initial column-gap: 9;
direction VisualElement ltr | rtl | inherit | initial direction: rtl;
flex-direction FlexLayout column | columnreverse | row | rowreverse | row-reverse | column-reverse | initial flex-direction: column-reverse;
flex-basis VisualElement float | | autoinitial. Кроме того, можно указать процент в диапазоне от 0 до 100 % с % помощью знака. flex-basis: 25%;
flex-grow VisualElement float | initial flex-grow: 1.5;
flex-shrink VisualElement float | initial flex-shrink: 1;
flex-wrap VisualElement nowrap | wrap | reverse | wrap-reverse | initial flex-wrap: wrap-reverse;
font-family Button, DatePickerEditorEntryLabelPickerSearchBarTimePickerSpan string | initial font-family: Consolas;
font-size Button, DatePickerEditorEntryLabelPickerSearchBarTimePickerSpan double | namedsize | initial font-size: 12;
font-style Button, DatePickerEditorEntryLabelPickerSearchBarTimePickerSpan bold | italic | initial font-style: bold;
height VisualElement double | initial min-height: 250;
justify-content FlexLayout start | center | end | spacebetween | spacearound | spaceevenly | flex-start | flex-end | space-between | space-around | initial justify-content: flex-end;
letter-spacing Button, DatePicker, EditorEntryLabelPickerSearchBarSearchHandlerSpanTimePicker double | initial letter-spacing: 2.5;
line-height Label, Span double | initial line-height: 1.8;
margin View Толщина | initial margin: 6 12;
margin-left View Толщина | initial margin-left: 3;
margin-top View Толщина | initial margin-top: 2;
margin-right View Толщина | initial margin-right: 1;
margin-bottom View Толщина | initial margin-bottom: 6;
max-lines Label int | initial max-lines: 2;
min-height VisualElement double | initial min-height: 50;
min-width VisualElement double | initial min-width: 112;
opacity VisualElement double | initial opacity: .3;
order VisualElement int | initial order: -1;
padding Button, , ImageButtonLayoutPage Толщина | initial padding: 6 12 12;
padding-left Button, , ImageButtonLayoutPage double | initial padding-left: 3;
padding-top Button, , ImageButtonLayoutPage double | initial padding-top: 4;
padding-right Button, , ImageButtonLayoutPage double | initial padding-right: 2;
padding-bottom Button, , ImageButtonLayoutPage double | initial padding-bottom: 6;
position FlexLayout relative | absolute | initial position: absolute;
row-gap Grid double | initial row-gap: 12;
text-align Entry, , EntryCellLabelSearchBar left | top | right | bottom | start | center | middle | end | initial. left и right следует избегать в средах справа налево. text-align: right;
text-decoration Label, Span none | underline | strikethrough | line-through | initial text-decoration: underline, line-through;
text-transform Button,Editor, , LabelEntry, SearchBarSearchHandler none | default | uppercase | lowercase | initial text-transform: uppercase;
transform VisualElement none, rotate, rotateXrotateYscalescaleXscaleYtranslatetranslateXtranslateYinitial transform: rotate(180), scaleX(2.5);
transform-origin VisualElement double, double | initial transform-origin: 7.5, 12.5;
vertical-align Label left | top | right | bottom | start | center | middle | end | initial vertical-align: bottom;
visibility VisualElement true | visible | false | hidden | collapse | initial visibility: hidden;
width VisualElement double | initial min-width: 320;

Примечание.

initial является допустимым значением для всех свойств. Он очищает значение (сбрасывается по умолчанию), которое было задано из другого стиля.

В настоящее время неподдерживаемые свойства:

  • all: initial.
  • Свойства макета (поле или сетка).
  • Короткие свойства, такие как font, и border.

Кроме того, нет inherit значения и поэтому наследование не поддерживается. Поэтому нельзя, например, задать font-size свойство макета и ожидать, что все Label экземпляры в макете наследуют значение. Одним из исключений direction является свойство, которое имеет значение inheritпо умолчанию.

У целевых элементов есть известная Span проблема, препятствующая тому, чтобы диапазоны были целевыми стилями CSS как по элементу, так и по имени (с помощью символа # ). Элемент Span является производным от GestureElementсвойства, поэтому диапазоны не StyleClass поддерживают назначение класса CSS. Дополнительные сведения см. в статье "Не удается применить стили CSS к элементу управления Span".

Xamarin.Forms определенные свойства

Также поддерживаются следующие Xamarin.Forms свойства CSS (в столбце "Значения" типы курсивны, а строковые литералы):gray

Свойство Применяется к Values Пример
-xf-bar-background-color NavigationPage, TabbedPage color | initial -xf-bar-background-color: teal;
-xf-bar-text-color NavigationPage, TabbedPage color | initial -xf-bar-text-color: gray
-xf-horizontal-scroll-bar-visibility ScrollView default | always | never | initial -xf-horizontal-scroll-bar-visibility: never;
-xf-max-length Entry, , EditorSearchBar int | initial -xf-max-length: 20;
-xf-max-track-color Slider color | initial -xf-max-track-color: red;
-xf-min-track-color Slider color | initial -xf-min-track-color: yellow;
-xf-orientation ScrollView, StackLayout horizontal | vertical | both | initial. both поддерживается только в объекте ScrollView. -xf-orientation: horizontal;
-xf-placeholder Entry, , EditorSearchBar в кавычках текст | initial -xf-placeholder: Enter name;
-xf-placeholder-color Entry, , EditorSearchBar color | initial -xf-placeholder-color: green;
-xf-spacing StackLayout double | initial -xf-spacing: 8;
-xf-thumb-color Slider, Switch color | initial -xf-thumb-color: limegreen;
-xf-vertical-scroll-bar-visibility ScrollView default | always | never | initial -xf-vertical-scroll-bar-visibility: always;
-xf-vertical-text-alignment Label start | center | end | initial -xf-vertical-text-alignment: end;
-xf-visual VisualElement string | initial -xf-visual: material;

Xamarin.Forms Свойства оболочки

Также поддерживаются следующие Xamarin.Forms свойства CSS оболочки (в столбце "Значения", типы курсивны, а строковые литералы):gray

Свойство Применяется к Values Пример
-xf-flyout-background Shell color | initial -xf-flyout-background: red;
-xf-shell-background Element color | initial -xf-shell-background: green;
-xf-shell-disabled Element color | initial -xf-shell-disabled: blue;
-xf-shell-foreground Element color | initial -xf-shell-foreground: yellow;
-xf-shell-tabbar-background Element color | initial -xf-shell-tabbar-background: white;
-xf-shell-tabbar-disabled Element color | initial -xf-shell-tabbar-disabled: black;
-xf-shell-tabbar-foreground Element color | initial -xf-shell-tabbar-foreground: gray;
-xf-shell-tabbar-title Element color | initial -xf-shell-tabbar-title: lightgray;
-xf-shell-tabbar-unselected Element color | initial -xf-shell-tabbar-unselected: cyan;
-xf-shell-title Element color | initial -xf-shell-title: teal;
-xf-shell-unselected Element color | initial -xf-shell-unselected: limegreen;

Color

Поддерживаются следующие color значения:

  • X11цвета, соответствующие цветам CSS, предварительно определенным цветам и Xamarin.Forms цветам UWP. Обратите внимание, что эти значения цвета являются нечувствительными к регистру.
  • шестнадцатеричные цвета: #rgb, #argb, #rrggbb#aarrggbb
  • rgb colors: rgb(255,0,0), rgb(100%,0%,0%). Значения находятся в диапазоне от 0 до 255 или 0%-100%.
  • цвета rgba: rgba(255, 0, 0, 0.8), rgba(100%, 0%, 0%, 0.8). Значение непрозрачности находится в диапазоне 0.0-1.0.
  • цвета hsl: hsl(120, 100%, 50%). Значение h находится в диапазоне от 0 до 360, а s и l находятся в диапазоне 0%-100%.
  • цвета hsla: hsla(120, 100%, 50%, .8). Значение непрозрачности находится в диапазоне 0.0-1.0.

Толщина

Поддерживаются один, два, три или четыре thickness значения, разделенные пробелами:

  • Одно значение указывает на единую толщину.
  • Два значения указывают вертикальную, а затем горизонтальную толщину.
  • Три значения указывают верхнюю, а затем горизонтальную (левую и правую), а затем толщину нижнего.
  • Четыре значения указывают верхнюю, а затем справа, а затем внизу, а затем левую толщину.

Примечание.

Значения CSS thickness отличаются от значений XAML Thickness . Например, в XAML двухзначное значение Thickness указывает горизонтальную и вертикальную толщину, а четыре значения Thickness — левую, а затем верхнюю, а затем справа, а затем толщину нижнего. Кроме того, значения XAML Thickness разделены запятыми.

Именованный размер

Поддерживаются следующие нечувствительные namedsize значения регистра:

  • default
  • micro
  • small
  • medium
  • large

Точное значение каждого namedsize значения зависит от платформы и зависит от представления.

Функции

Линейные и радиальные градиенты можно указать с помощью linear-gradient() функций и radial-gradient() CSS соответственно. Результат этих функций должен быть назначен background свойству элемента управления.

CSS в Xamarin.Forms Xamarin.University

Xamarin.Forms 3.0 CSS видео