Наследование стилей в Xamarin.Forms

Стили могут наследовать от других стилей, чтобы уменьшить дублирование и включить повторное использование.

Наследование стилей в XAML

Наследование стилей Style.BasedOn выполняется путем задания свойства существующему Style. В XAML это достигается путем установки BasedOn свойства StaticResource в расширение разметки, которое ссылается на ранее созданное расширение Style. В C#это достигается путем задания BasedOn свойства экземпляру Style .

Стили, наследуемые от базового стиля, могут включать Setter экземпляры для новых свойств или использовать их для переопределения стилей из базового стиля. Кроме того, стили, наследуемые от базового стиля, должны нацелены на тот же тип или тип, производный от типа, наследуемого базовым стилем. Например, если базовый стиль предназначен View для экземпляров, стили, основанные на базовом стиле, могут целевые View экземпляры или типы, производные от View класса, например LabelButton и экземпляров.

Следующий код демонстрирует явное наследование стилей на странице XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.StyleInheritancePage" Title="Inheritance" IconImageSource="xaml.png">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="baseStyle" TargetType="View">
                <Setter Property="HorizontalOptions"
                        Value="Center" />
                <Setter Property="VerticalOptions"
                        Value="CenterAndExpand" />
            </Style>
            <Style x:Key="labelStyle" TargetType="Label"
                   BasedOn="{StaticResource baseStyle}">
                ...
                <Setter Property="TextColor" Value="Teal" />
            </Style>
            <Style x:Key="buttonStyle" TargetType="Button"
                   BasedOn="{StaticResource baseStyle}">
                <Setter Property="BorderColor" Value="Lime" />
                ...
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <StackLayout Padding="0,20,0,0">
            <Label Text="These labels"
                   Style="{StaticResource labelStyle}" />
            ...
            <Button Text="So is the button"
                    Style="{StaticResource buttonStyle}" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

View Целевые baseStyle экземпляры и задает HorizontalOptions свойства.VerticalOptions Параметр baseStyle не задан непосредственно для элементов управления. Вместо этого и buttonStyle наследуется от него, labelStyle задав дополнительные значения привязываемого свойства. buttonStyle Затем labelStyle они применяются к Label экземплярам и Button экземплярам, задав их Style свойства. Результат показан на следующих снимках экрана:

Снимок экрана наследования стилей

Примечание.

Неявный стиль может быть производным от явного стиля, но явный стиль не может быть производным от неявного стиля.

Уважение цепочки наследования

Стиль может наследоваться только от стилей на том же уровне или выше в иерархии представлений. Это означает следующее.

  • Ресурс уровня приложения может наследовать только от других ресурсов уровня приложения.
  • Ресурс уровня страницы может наследоваться от ресурсов уровня приложения и других ресурсов уровня страницы.
  • Ресурс уровня управления может наследоваться от ресурсов уровня приложения, ресурсов уровня страницы и других ресурсов уровня управления.

Эта цепочка наследования показана в следующем примере кода:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.StyleInheritancePage" Title="Inheritance" IconImageSource="xaml.png">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="baseStyle" TargetType="View">
              ...
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <StackLayout Padding="0,20,0,0">
            <StackLayout.Resources>
                <ResourceDictionary>
                    <Style x:Key="labelStyle" TargetType="Label" BasedOn="{StaticResource baseStyle}">
                      ...
                    </Style>
                    <Style x:Key="buttonStyle" TargetType="Button" BasedOn="{StaticResource baseStyle}">
                      ...
                    </Style>
                </ResourceDictionary>
            </StackLayout.Resources>
            ...
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

В этом примере labelStyle и buttonStyle являются ресурсами уровня управления, а это baseStyle ресурс уровня страницы. Тем не менее, в то время как labelStyle и buttonStyle наследование от , невозможно baseStyle наследовать baseStyleот labelStyle или buttonStyleиз-за их соответствующих расположений в иерархии представлений.

Наследование стилей в C#

Эквивалентная страница C#, где Style экземпляры назначаются непосредственно Style свойствам обязательных элементов управления, показана в следующем примере кода:

public class StyleInheritancePageCS : ContentPage
{
    public StyleInheritancePageCS ()
    {
        var baseStyle = new Style (typeof(View)) {
            Setters = {
                new Setter {
                    Property = View.HorizontalOptionsProperty, Value = LayoutOptions.Center    },
                ...
            }
        };

        var labelStyle = new Style (typeof(Label)) {
            BasedOn = baseStyle,
            Setters = {
                ...
                new Setter { Property = Label.TextColorProperty, Value = Color.Teal    }
            }
        };

        var buttonStyle = new Style (typeof(Button)) {
            BasedOn = baseStyle,
            Setters = {
                new Setter { Property = Button.BorderColorProperty, Value =    Color.Lime },
                ...
            }
        };
        ...

        Content = new StackLayout {
            Children = {
                new Label { Text = "These labels", Style = labelStyle },
                ...
                new Button { Text = "So is the button", Style = buttonStyle }
            }
        };
    }
}

View Целевые baseStyle экземпляры и задает HorizontalOptions свойства.VerticalOptions Параметр baseStyle не задан непосредственно для элементов управления. Вместо этого и buttonStyle наследуется от него, labelStyle задав дополнительные значения привязываемого свойства. buttonStyle Затем labelStyle они применяются к Label экземплярам и Button экземплярам, задав их Style свойства.