Ereditarietà dello stile in Xamarin.Forms

Gli stili possono ereditare da altri stili per ridurre la duplicazione e abilitare il riutilizzo.

Ereditarietà dello stile in XAML

L'ereditarietà dello stile viene eseguita impostando la Style.BasedOn proprietà su un oggetto esistente Style. In XAML questa operazione viene ottenuta impostando la BasedOn proprietà su un'estensione StaticResource di markup che fa riferimento a un oggetto creato Stylein precedenza. In C#, questa operazione viene ottenuta impostando la proprietà su un'istanza BasedOnStyle di .

Gli stili che ereditano da uno stile di base possono includere Setter istanze per le nuove proprietà o usarle per eseguire l'override degli stili dallo stile di base. Inoltre, gli stili che ereditano da uno stile di base devono avere come destinazione lo stesso tipo o un tipo che deriva dal tipo di destinazione dello stile di base. Ad esempio, se un tipo di stile View di base è destinato alle istanze di , gli stili basati sullo stile di base possono essere destinati View a istanze o tipi che derivano dalla View classe , ad esempio Label e Button .

Il codice seguente illustra l'ereditarietà esplicita dello stile in una pagina 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>

Le istanze di baseStyle destinazione View e impostano le HorizontalOptions proprietà e VerticalOptions . l'oggetto baseStyle non è impostato direttamente su alcun controllo. Al contrario, labelStyle e buttonStyle ereditano da esso, impostando valori di proprietà associabili aggiuntivi. E labelStylebuttonStyle vengono quindi applicati alle istanze e Button all'istanza Label impostando le relative Style proprietà. Il risultato è l'aspetto illustrato negli screenshot seguenti:

Screenshot dell'ereditarietà dello stile

Nota

Uno stile implicito può essere derivato da uno stile esplicito, ma non è possibile derivare uno stile esplicito da uno stile implicito.

Rispetto della catena di ereditarietà

Uno stile può ereditare solo da stili allo stesso livello, o superiore, nella gerarchia di visualizzazione. Ciò significa che:

  • Una risorsa a livello di applicazione può ereditare solo da altre risorse a livello di applicazione.
  • Una risorsa a livello di pagina può ereditare da risorse a livello di applicazione e altre risorse a livello di pagina.
  • Una risorsa a livello di controllo può ereditare da risorse a livello di applicazione, risorse a livello di pagina e altre risorse a livello di controllo.

Questa catena di ereditarietà è illustrata nell'esempio di codice seguente:

<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>

In questo esempio labelStyle e buttonStyle sono risorse a livello di controllo, mentre baseStyle è una risorsa a livello di pagina. Tuttavia, mentre labelStyle e buttonStyle ereditano da baseStyle, non è possibile baseStyle ereditare da labelStyle o buttonStyle, a causa delle rispettive posizioni nella gerarchia di visualizzazione.

Ereditarietà dello stile in C#

La pagina C# equivalente, in cui Style le istanze vengono assegnate direttamente alle Style proprietà dei controlli necessari, viene illustrato nell'esempio di codice seguente:

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 }
            }
        };
    }
}

Le istanze di baseStyle destinazione View e impostano le HorizontalOptions proprietà e VerticalOptions . l'oggetto baseStyle non è impostato direttamente su alcun controllo. Al contrario, labelStyle e buttonStyle ereditano da esso, impostando valori di proprietà associabili aggiuntivi. E labelStylebuttonStyle vengono quindi applicati alle istanze e Button all'istanza Label impostando le relative Style proprietà.