Стилизация Xamarin.Forms приложений с помощью каскадных таблиц стилей (CSS)
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.
Пример демонстрирует использование CSS для стиля простого приложения и показан на следующих снимках экрана:
Использование таблицы стилей
Процесс добавления таблицы стилей в решение выглядит следующим образом:
- Добавьте пустой CSS-файл в проект библиотеки .NET Standard.
- Задайте для действия сборки CSS-файла значение EmbeddedResource.
Загрузка таблицы стилей
Существует ряд подходов, которые можно использовать для загрузки таблицы стилей.
Примечание.
В настоящее время невозможно изменить таблицу стилей во время выполнения и применить новую таблицу стилей.
XAML
Таблицу стилей можно загрузить и проанализировать с StyleSheet
классом ResourceDictionary
перед добавлением в :
<Application ...>
<Application.Resources>
<StyleSheet Source="/Assets/styles.css" />
</Application.Resources>
</Application>
Свойство StyleSheet.Source
задает таблицу стилей в виде URI относительно расположения включающего XAML-файла или относительно корневого каталога проекта, если универсальный код ресурса (URI) начинается с /
.
Предупреждение
CSS-файл не будет загружаться, если его действие сборки не задано как EmbeddedResource.
Кроме того, таблицу стилей можно загрузить и проанализировать с StyleSheet
классом, прежде чем добавлять его в ResourceDictionary
CDATA
раздел.
<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 |
Выбирает все элементы и все Button Label элементы. Обратите внимание, что этот селектор не учитывает регистр. |
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
Свойство | Применяется к | Значения | Пример |
---|---|---|---|
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 , , Frame ImageButton |
color | initial |
border-color: #9acd32; |
border-radius |
BoxView , , Button Frame ImageButton |
double | initial |
border-radius: 10; |
border-width |
Button , ImageButton |
double | initial |
border-width: .5; |
color |
ActivityIndicator , BoxView , Button CheckBox DatePicker Editor Entry Label Picker ProgressBar SearchBar Switch TimePicker |
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 | | auto initial . Кроме того, можно указать процент в диапазоне от 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 , DatePicker Editor Entry Label Picker SearchBar TimePicker Span |
string | initial |
font-family: Consolas; |
font-size |
Button , DatePicker Editor Entry Label Picker SearchBar TimePicker Span |
double | namedsize | initial |
font-size: 12; |
font-style |
Button , DatePicker Editor Entry Label Picker SearchBar TimePicker Span |
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 , Editor Entry Label Picker SearchBar SearchHandler Span TimePicker |
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 , , ImageButton Layout Page |
толщина | initial |
padding: 6 12 12; |
padding-left |
Button , , ImageButton Layout Page |
double | initial |
padding-left: 3; |
padding-top |
Button , , ImageButton Layout Page |
double | initial |
padding-top: 4; |
padding-right |
Button , , ImageButton Layout Page |
double | initial |
padding-right: 2; |
padding-bottom |
Button , , ImageButton Layout Page |
double | initial |
padding-bottom: 6; |
position |
FlexLayout |
relative | absolute | initial |
position: absolute; |
row-gap |
Grid |
double | initial |
row-gap: 12; |
text-align |
Entry , , EntryCell Label SearchBar |
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 , , Label Entry , SearchBar SearchHandler |
none | default | uppercase | lowercase | initial |
text-transform: uppercase; |
transform |
VisualElement |
none , rotate , rotateX rotateY scale scaleX scaleY translate translateX translateY initial |
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
Свойство | Применяется к | Значения | Пример |
---|---|---|---|
-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 , , Editor SearchBar |
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 , , Editor SearchBar |
в кавычках текст | initial |
-xf-placeholder: Enter name; |
-xf-placeholder-color |
Entry , , Editor SearchBar |
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
Свойство | Применяется к | Значения | Пример |
---|---|---|---|
-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 видео