Udostępnij za pośrednictwem


Aplikacje stylów korzystające z kaskadowych arkuszy stylów

Aplikacje .NET MAUI (interfejs wieloplatformowy aplikacji) można stylizować za pomocą kaskadowych arkuszy stylów (CSS). Arkusz stylów składa się z listy reguł, z których każda zawiera co najmniej jeden selektor i blok deklaracji. Blok deklaracyjny składa się z listy deklaracji w nawiasach klamrowych, gdzie każda deklaracja składa się z właściwości, dwukropka i wartości. Jeśli w bloku znajduje się wiele deklaracji, średnik jest wstawiany jako separator.

W poniższym przykładzie przedstawiono kod CSS zgodny ze standardem MAUI platformy .NET:

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

^contentpage {
    background-color: lightgray;
}

#listView {
    background-color: lightgray;
}

stacklayout {
    margin: 20;
    -maui-spacing: 6;
}

grid {
    row-gap: 6;
    column-gap: 6;
}
.mainPageTitle {
    font-style: bold;
    font-size: 14;
}

.mainPageSubtitle {
    margin-top: 15;
}

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

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

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

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

W programie .NET MAUI arkusze stylów CSS są analizowane i oceniane w czasie wykonywania, a nie w czasie kompilacji, a arkusze stylów są ponownie analizowane.

Ważny

Nie można w pełni stylizować aplikacji .NET MAUI przy użyciu arkuszy CSS. Jednak style XAML mogą służyć do uzupełnienia css. Aby uzyskać więcej informacji na temat stylów XAML, zobacz Style apps using XAML.

Korzystanie z arkusza stylów

Proces dodawania arkusza stylów do aplikacji MAUI platformy .NET jest następujący:

  1. Dodaj pusty plik CSS do projektu aplikacji .NET MAUI. Plik CSS można umieścić w dowolnym folderze, a folder Resources jest zalecaną lokalizacją.
  2. Ustaw akcję kompilacji pliku CSS na MauiCss.

Ładowanie arkusza stylów

Istnieje wiele podejść, których można użyć do załadowania arkusza stylów.

Notatka

Nie można zmienić arkusza stylów w trakcie działania programu i zastosować nowego arkusza stylów.

Ładowanie arkusza stylów w języku XAML

Arkusz stylów można załadować i przeanalizować z klasą StyleSheet przed dodaniu do ResourceDictionary:

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

Właściwość StyleSheet.Source określa arkusz stylów jako identyfikator URI względem lokalizacji otaczającego pliku XAML lub względem katalogu głównego projektu, jeśli identyfikator URI rozpoczyna się od /.

Ostrzeżenie

Nie można załadować pliku CSS, jeśli jego akcja kompilacji nie jest ustawiona na MauiCss.

Alternatywnie arkusz stylów można załadować i przeanalizować z klasą StyleSheet, zanim zostanie on dodany do ResourceDictionary, umieszczając go bezpośrednio w sekcji CDATA.

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

Aby uzyskać więcej informacji na temat słowników zasobów, zobacz Słowniki zasobów.

Ładowanie arkusza stylów w języku C#

W języku C#arkusz stylów można załadować z StringReader i dodać go do ResourceDictionary:

using Microsoft.Maui.Controls.StyleSheets;

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

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

Argumentem metody StyleSheet.FromReader jest TextReader, który odczytał arkusz stylów.

Wybieranie elementów i stosowanie właściwości

Arkusz CSS używa selektorów do określania elementów docelowych. Style z pasującymi selektorami są stosowane kolejno w kolejności definicji. Style zdefiniowane na określonym elemencie są zawsze stosowane jako ostatnie. Aby uzyskać więcej informacji na temat obsługiwanych selektorów, zobacz Selektor referencyjny.

CSS używa właściwości do stylizacji wybranego elementu. Każda właściwość ma zestaw możliwych wartości, a niektóre właściwości mogą mieć wpływ na dowolny typ elementu, podczas gdy inne mają zastosowanie do grup elementów. Aby uzyskać więcej informacji na temat obsługiwanych właściwości, zobacz Odniesienie do właściwości.

Arkusze stylów podrzędnych zawsze zastępują nadrzędne arkusze stylów, jeśli ustawiają te same właściwości. W związku z tym następujące reguły pierwszeństwa są przestrzegane podczas stosowania stylów, które ustawiają te same właściwości:

  • Styl zdefiniowany w zasobach aplikacji zostanie zastąpiony przez styl zdefiniowany w zasobach strony, jeśli ustawi te same właściwości.
  • Styl zdefiniowany w zasobach strony zostanie zastąpiony przez styl zdefiniowany w zasobach sterujących, jeśli ustawi te same właściwości.
  • Styl zdefiniowany w zasobach aplikacji zostanie zastąpiony przez styl zdefiniowany w zasobach sterujących, jeśli ustawi te same właściwości.

Notatka

Zmienne CSS nie są obsługiwane.

Wybieranie elementów według typu

Elementy w drzewie wizualnym można wybierać według typu za pomocą selektora element, który nie uwzględnia wielkości liter.

stacklayout {
    margin: 20;
}

Ten selektor identyfikuje wszystkie elementy StackLayout na stronach korzystających z arkusza stylów i ustawia ich marginesy na jednolitą grubość 20.

Nota

Selektor element nie identyfikuje podklas określonego typu.

Wybieranie elementów według klasy bazowej

Elementy w drzewie wizualizacji można wybrać według klasy bazowej z selektorem bez uwzględniania wielkości liter ^base:

^contentpage {
    background-color: lightgray;
}

Ten selektor identyfikuje wszystkie elementy ContentPage, które używają arkusza stylów, i ustawia kolor tła na lightgray.

Notatka

Selektor ^base jest specyficzny dla interfejsu MAUI platformy .NET i nie jest częścią specyfikacji CSS.

Wybieranie elementu według nazwy

Poszczególne elementy w drzewie wizualizacji można wybrać za pomocą selektora uwzględniającego wielkość liter #id:

#listView {
    background-color: lightgray;
}

Ten selektor identyfikuje element, którego właściwość StyleId jest ustawiona na wartość listView. Jeśli jednak właściwość StyleId nie jest ustawiona, selektor powróci do używania x:Name elementu. W związku z tym w poniższym przykładzie selektor #listView zidentyfikuje ListView, którego atrybut x:Name jest ustawiony na listView, i ustawi kolor tła na lightgray.

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

Wybieranie elementów z określonym atrybutem klasy

Elementy z określonym atrybutem klasy można wybierać za pomocą selektora uwzględniającego wielkość liter, takiego jak .class.

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

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

Klasę CSS można przypisać do elementu XAML, ustawiając właściwość StyleClass elementu na nazwę klasy CSS. Dlatego w poniższym przykładzie style zdefiniowane przez klasę .detailPageTitle są przypisywane do pierwszego Label, podczas gdy style zdefiniowane przez klasę .detailPageSubtitle są przypisywane do drugiej Label.

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

Wybieranie elementów podrzędnych

Elementy podrzędne w drzewie wizualnym można wybrać przy użyciu selektora bez uwzględniania wielkości liter element element:

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

Ten selektor identyfikuje wszystkie elementy Image, które są elementami podrzędnymi elementów ListView, i ustawia ich wysokość i szerokość na 60. W związku z tym w poniższym przykładzie XAML selektor listview image zidentyfikuje Image, który jest elementem podrzędnym ListView, i ustawia jego wysokość i szerokość na 60.

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

Notatka

Selektor element element nie wymaga, aby element podrzędny był elementem bezpośrednim elementu nadrzędnego — element podrzędny może mieć inny element nadrzędny. Wybór występuje pod warunkiem, że przodek jest określonym pierwszym elementem.

Wybieranie bezpośrednich elementów podrzędnych

Bezpośrednie elementy podrzędne w drzewie wizualizacji można wybrać z selektorem bez uwzględniania wielkości liter element>element:

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

Ten selektor identyfikuje wszystkie elementy Image, które są bezpośrednimi elementami podrzędnymi elementów StackLayout, i ustawia ich wysokość i szerokość na 200. W związku z tym w poniższym przykładzie selektor stacklayout>image zidentyfikuje Image, który jest bezpośrednim elementem podrzędnym StackLayouti ustawia jego wysokość i szerokość na 200.

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

Notatka

Selektor element>element wymaga, aby element podrzędny był elementem bezpośrednim elementu nadrzędnego.

Odniesienie do selektora

Następujące selektory CSS są obsługiwane przez program .NET MAUI:

Selektor Przykład Opis
.class .header Wybiera wszystkie elementy z właściwością StyleClass zawierającą "nagłówek". W selektorze jest uwzględniana wielkość liter.
#id #email Wybiera wszystkie elementy, dla których StyleId jest ustawione na email. Jeśli StyleId nie jest ustawiona, przejdź do x:Name. W przypadku korzystania z języka XAML preferowane jest użycie x:Name w StyleId. W selektorze jest uwzględniana wielkość liter.
* * Wybiera wszystkie elementy.
element label Wybiera wszystkie elementy typu Label, ale nie podklasy. Ten selektor jest niewrażliwy na wielkość liter.
^base ^contentpage Wybiera wszystkie elementy z ContentPage jako klasą bazową, w tym sam ContentPage. Ten selektor nie uwzględnia wielkości liter i nie jest częścią specyfikacji CSS.
element,element label,button Wybiera wszystkie elementy Button i wszystkie elementy Label. Ten selektor jest niewrażliwy na wielkość liter.
element element stacklayout label Wybiera wszystkie elementy Label znajdujące się wewnątrz StackLayout. Ten selektor jest niewrażliwy na wielkość liter.
element>element stacklayout>label Wybiera wszystkie elementy Label, które mają StackLayout jako bezpośredniego rodzica. Ten selektor jest niewrażliwy na wielkość liter.
element+element label+entry Wybiera wszystkie elementy Entry, które są bezpośrednio po Label. Ten selektor jest niewrażliwy na wielkość liter.
element~element label~entry Wybiera wszystkie elementy Entry poprzedzone przez Label. Ten selektor jest niewrażliwy na wielkość liter.

Style z pasującymi selektorami są stosowane kolejno w kolejności definicji. Style zdefiniowane na określonym elemencie są zawsze stosowane jako ostatnie.

Napiwek

Selektory można łączyć bez ograniczeń, na przykład StackLayout>ContentView>label.email.

Następujące selektory nie są obsługiwane:

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

Notatka

Specyfika i przesłonięcia priorytetowe są nieobsługiwane.

Jeśli co najmniej dwie reguły CSS wskazują ten sam element, selektor o najwyższej specyfiki będzie mieć pierwszeństwo, a jego deklaracja stylu zostanie zastosowana do elementu. Algorytm specyficzności oblicza wagę selektora CSS w celu określenia, która reguła z konkurujących deklaracji CSS zostanie zastosowana do elementu.

Referencja właściwości

Następujące właściwości CSS są obsługiwane przez program .NET MAUI (w kolumnie wartości typy są kursywą, podczas gdy literały ciągu są gray):

Własność Dotyczy Wartości Przykład
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 kolor | initial background-color: springgreen;
background-image Page ciągu | initial background-image: bg.png;
border-color Button, Frame, ImageButton kolor | initial border-color: #9acd32;
border-radius BoxView, Button, Frame, ImageButton podwójne | initial border-radius: 10;
border-width Button, ImageButton podwójne | initial border-width: .5;
color ActivityIndicator, BoxView, Button, CheckBox, DatePicker, Editor, Entry, Label, Picker, ProgressBar, SearchBar, Switch, TimePicker Kolor | initial color: rgba(255, 0, 0, 0.3);
column-gap Grid podwójne | 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. Ponadto można określić wartość procentową w zakresie od 0% do 100% za pomocą znaku %. flex-basis: 25%;
flex-grow VisualElement liczba zmiennoprzecinkowa | initial flex-grow: 1.5;
flex-shrink VisualElement zmiennoprzecinkowy | 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 ciąg | initial font-family: Consolas;
font-size Button, DatePicker, Editor, Entry, Label, Picker, SearchBar, TimePicker, Span podwójne | initial font-size: 12;
font-style Button, DatePicker, Editor, Entry, Label, Picker, SearchBar, TimePicker, Span bold | italic | initial font-style: bold;
height VisualElement podwójne | initial 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 podwójne | initial letter-spacing: 2.5;
line-height Label, Span podwójne | initial line-height: 1.8;
margin View Grubość | initial margin: 6 12;
margin-left View grubości | initial margin-left: 3;
margin-top View grubości | initial margin-top: 2;
margin-right View grubości | initial margin-right: 1;
margin-bottom View grubości | initial margin-bottom: 6;
max-lines Label int | initial max-lines: 2;
min-height VisualElement podwójne | initial min-height: 50;
min-width VisualElement podwójne | initial min-width: 112;
opacity VisualElement podwójne | initial opacity: .3;
order VisualElement int | initial order: -1;
padding Button, ImageButton, Layout, Page grubość | initial padding: 6 12 12;
padding-left Button, ImageButton, Layout, Page podwójne | initial padding-left: 3;
padding-top Button, ImageButton, Layout, Page podwójne | initial padding-top: 4;
padding-right Button, ImageButton, Layout, Page podwójne | initial padding-right: 2;
padding-bottom Button, ImageButton, Layout, Page podwójne | initial padding-bottom: 6;
position FlexLayout relative | absolute | initial position: absolute;
row-gap Grid podwójne | initial row-gap: 12;
text-align Entry, EntryCell, Label, SearchBar left | top | right | bottom | start | center | middle | end | initial. left i right należy unikać w środowiskach o układzie od prawej do lewej. text-align: right;
text-decoration Label, Span none | underline | strikethrough | line-through | initial text-decoration: underline, line-through;
text-transform Button,Editor, Entry, Label, 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 podwójne, podwójne | 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 podwójne | initial width: 320;

Notatka

initial jest prawidłową wartością dla wszystkich właściwości. Spowoduje to wyczyszczenie wartości (resetuje wartość domyślną), która została ustawiona z innego stylu.

Następujące właściwości nie są obsługiwane:

  • all: initial.
  • Właściwości układu (pole lub siatka).
  • Właściwości skrótowe, takie jak fonti border.

Ponadto nie ma wartości inherit, dlatego dziedziczenie nie jest obsługiwane. W związku z tym nie można na przykład ustawić właściwości font-size w układzie i oczekiwać, że wszystkie wystąpienia Label w układzie będą dziedziczyć wartość. Jednym wyjątkiem jest właściwość direction, która ma wartość domyślną inherit.

Ważny

Span elementów nie można celować za pomocą CSS.

Właściwości specyficzne dla interfejsu MAUI platformy .NET

Obsługiwane są również następujące właściwości CSS specyficzne dla .NET MAUI (w kolumnie wartości typy są kursywą, a literały łańcuchowe są gray):

Własność Dotyczy Wartości Przykład
-maui-bar-background-color NavigationPage, TabbedPage kolor | initial -maui-bar-background-color: teal;
-maui-bar-text-color NavigationPage, TabbedPage kolor | initial -maui-bar-text-color: gray
-maui-horizontal-scroll-bar-visibility ScrollView default | always | never | initial -maui-horizontal-scroll-bar-visibility: never;
-maui-max-length Entry, Editor, SearchBar int | initial -maui-max-length: 20;
-maui-max-track-color Slider kolor | initial -maui-max-track-color: red;
-maui-min-track-color Slider kolor | initial -maui-min-track-color: yellow;
-maui-orientation ScrollView, StackLayout horizontal | vertical | both | initial. both jest obsługiwana tylko w ScrollView. -maui-orientation: horizontal;
-maui-placeholder Entry, Editor, SearchBar cytowany tekst | initial -maui-placeholder: Enter name;
-maui-placeholder-color Entry, Editor, SearchBar kolor | initial -maui-placeholder-color: green;
-maui-spacing StackLayout podwójne | initial -maui-spacing: 8;
-maui-shadow VisualElement Prawidłowe formaty to: kolor, offsetX, offsetY | przesunięcie X, przesunięcie Y, promień, kolor | przesunięcie X, przesunięcie Y, promień, kolor, opactiość -maui-shadow: #000000 4 4;
-maui-thumb-color Slider, Switch kolor | initial -maui-thumb-color: limegreen;
-maui-vertical-scroll-bar-visibility ScrollView default | always | never | initial -maui-vertical-scroll-bar-visibility: always;
-maui-vertical-text-alignment Label start | center | end | initial -maui-vertical-text-alignment: end;
-maui-visual VisualElement ciąg | initial -maui-visual: material;

Właściwości specyficzne dla powłoki .NET MAUI

Obsługiwane są również następujące właściwości CSS specyficzne dla Powłoki .NET MAUI (w kolumnie wartości, typy są kursywą, podczas gdy ciągi znaków są gray):

Własność Dotyczy Wartości Przykład
-maui-flyout-background Shell kolor | initial -maui-flyout-background: red;
-maui-shell-background Element kolor | initial -maui-shell-background: green;
-maui-shell-disabled Element kolor | initial -maui-shell-disabled: blue;
-maui-shell-foreground Element kolor | initial -maui-shell-foreground: yellow;
-maui-shell-tabbar-background Element kolor | initial -maui-shell-tabbar-background: white;
-maui-shell-tabbar-disabled Element Kolor | initial -maui-shell-tabbar-disabled: black;
-maui-shell-tabbar-foreground Element kolor | initial -maui-shell-tabbar-foreground: gray;
-maui-shell-tabbar-title Element kolor | initial -maui-shell-tabbar-title: lightgray;
-maui-shell-tabbar-unselected Element kolor | initial -maui-shell-tabbar-unselected: cyan;
-maui-shell-title Element kolor | initial -maui-shell-title: teal;
-maui-shell-unselected Element kolor | initial -maui-shell-unselected: limegreen;

Kolor

Obsługiwane są następujące wartości color:

  • X11 kolory, które są zgodne z kolorami CSS i kolorami MAUI platformy .NET. Te wartości kolorów są niewrażliwe na wielkość liter.
  • Kolory szesnastkowe: #rgb, #argb, #rrggbb, #aarrggbb
  • kolory rgb: rgb(255,0,0), rgb(100%,0%,0%). Wartości znajdują się w zakresie od 0 do 255 lub 0%-100%.
  • kolory rgba: rgba(255, 0, 0, 0.8), rgba(100%, 0%, 0%, 0.8). Wartość nieprzezroczystości znajduje się w zakresie od 0,0 do 1,0.
  • kolory HSL: kod koloru hsl(120, 100%, 50%). Wartość h znajduje się w zakresie od 0 do 360, podczas gdy s i l znajdują się w zakresie 0%-100%.
  • kolory hsla: hsla(120, 100%, 50%, .8). Wartość nieprzezroczystości znajduje się w zakresie od 0,0 do 1,0.

Grubość

Obsługiwane są dwie, trzy lub cztery thickness wartości, z których każda jest oddzielona białym znakiem:

  • Pojedyncza wartość wskazuje jednolitą grubość.
  • Dwie wartości wskazują pionową, a następnie poziomą grubość.
  • Trzy wartości wskazują kolejno: górną, poziomą (lewą i prawą), a następnie dolną grubość.
  • Cztery wartości wskazują grubość od góry, prawej, dołu i lewej strony.

Notatka

Wartości thickness CSS różnią się od wartości Thickness XAML. Na przykład w języku XAML dwie wartości Thickness oznaczają grubość poziomą, a potem pionową, natomiast cztery wartości Thickness oznaczają grubość od lewej, potem górną, następnie prawą, a na końcu dolną. Ponadto wartości Thickness XAML są rozdzielane przecinkami.

Funkcje

Gradienty liniowe i promieniowe można określić odpowiednio przy użyciu funkcji linear-gradient() i radial-gradient() CSS. Wynik tych funkcji należy przypisać do właściwości background kontrolki.