Styles dynamiques dans Xamarin.Forms

Télécharger l’exemple Télécharger l’exemple

Les styles ne répondent pas aux modifications de propriété et restent inchangés pendant la durée d’une application. Par exemple, après avoir affecté un style à un élément visuel, si l’une des instances setter est modifiée, supprimée ou qu’une nouvelle instance ajoutée, les modifications ne sont pas appliquées à l’élément visuel. Toutefois, les applications peuvent répondre dynamiquement aux changements de style au moment de l’exécution à l’aide de ressources dynamiques.

L’extension DynamicResource de balisage est similaire à l’extension StaticResource de balisage en ce sens que les deux utilisent une clé de dictionnaire pour extraire une valeur d’un ResourceDictionary. Toutefois, pendant que effectue StaticResource une recherche de dictionnaire unique, le DynamicResource conserve un lien vers la clé de dictionnaire. Par conséquent, si l’entrée de dictionnaire associée à la clé est remplacée, la modification est appliquée à l’élément visuel. Cela permet d’apporter des modifications de style d’exécution dans une application.

L’exemple de code suivant illustre les styles dynamiques dans une page XAML :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.DynamicStylesPage" Title="Dynamic" IconImageSource="xaml.png">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="baseStyle" TargetType="View">
              ...
            </Style>
            <Style x:Key="blueSearchBarStyle"
                   TargetType="SearchBar"
                   BasedOn="{StaticResource baseStyle}">
              ...
            </Style>
            <Style x:Key="greenSearchBarStyle"
                   TargetType="SearchBar">
              ...
            </Style>
            ...
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <StackLayout Padding="0,20,0,0">
            <SearchBar Placeholder="These SearchBar controls"
                       Style="{DynamicResource searchBarStyle}" />
            ...
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Les SearchBar instances utilisent l’extension DynamicResource de balisage pour référencer un Style nommé searchBarStyle, qui n’est pas défini dans le xaml. Toutefois, étant donné que les Style propriétés des instances sont définies à l’aide SearchBar d’un DynamicResource, la clé de dictionnaire manquante n’entraîne pas la levée d’une exception.

Au lieu de cela, dans le fichier code-behind, le constructeur crée une ResourceDictionary entrée avec la clé searchBarStyle, comme indiqué dans l’exemple de code suivant :

public partial class DynamicStylesPage : ContentPage
{
    bool originalStyle = true;

    public DynamicStylesPage ()
    {
        InitializeComponent ();
        Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];
    }

    void OnButtonClicked (object sender, EventArgs e)
    {
        if (originalStyle) {
            Resources ["searchBarStyle"] = Resources ["greenSearchBarStyle"];
            originalStyle = false;
        } else {
            Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];
            originalStyle = true;
        }
    }
}

Lorsque le OnButtonClicked gestionnaire d’événements est exécuté, searchBarStyle bascule entre blueSearchBarStyle et greenSearchBarStyle. Cela donne l’affichage illustré dans les captures d’écran suivantes :

Exemple de style dynamique bleuExemple de style dynamique vert

L’exemple de code suivant illustre la page équivalente en C# :

public class DynamicStylesPageCS : ContentPage
{
    bool originalStyle = true;

    public DynamicStylesPageCS ()
    {
        ...
        var baseStyle = new Style (typeof(View)) {
            ...
        };
        var blueSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        var greenSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        ...
        var searchBar1 = new SearchBar { Placeholder = "These SearchBar controls" };
        searchBar1.SetDynamicResource (VisualElement.StyleProperty, "searchBarStyle");
        ...
        Resources = new ResourceDictionary ();
        Resources.Add ("blueSearchBarStyle", blueSearchBarStyle);
        Resources.Add ("greenSearchBarStyle", greenSearchBarStyle);
        Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];

        Content = new StackLayout {
            Children = { searchBar1, searchBar2, searchBar3, searchBar4,    button    }
        };
    }
    ...
}

En C#, les SearchBar instances utilisent la SetDynamicResource méthode pour référencer searchBarStyle. Le OnButtonClicked code du gestionnaire d’événements est identique à l’exemple XAML et, lorsqu’il est exécuté, searchBarStyle bascule entre blueSearchBarStyle et greenSearchBarStyle.

Héritage de style dynamique

La dérivation d’un style à partir d’un style dynamique ne peut pas être obtenue à l’aide de la Style.BasedOn propriété . Au lieu de cela, la classe inclut la BaseResourceKey propriété , qui peut être définie sur une clé de dictionnaire dont la Style valeur peut changer dynamiquement.

L’exemple de code suivant illustre l’héritage de style dynamique dans une page XAML :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.DynamicStylesInheritancePage" Title="Dynamic Inheritance" IconImageSource="xaml.png">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="baseStyle" TargetType="View">
              ...
            </Style>
            <Style x:Key="blueSearchBarStyle" TargetType="SearchBar" BasedOn="{StaticResource baseStyle}">
              ...
            </Style>
            <Style x:Key="greenSearchBarStyle" TargetType="SearchBar">
              ...
            </Style>
            <Style x:Key="tealSearchBarStyle" TargetType="SearchBar" BaseResourceKey="searchBarStyle">
              ...
            </Style>
            ...
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <StackLayout Padding="0,20,0,0">
            <SearchBar Text="These SearchBar controls" Style="{StaticResource tealSearchBarStyle}" />
            ...
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Les SearchBar instances utilisent l’extension de StaticResource balisage pour référencer un Style nommé tealSearchBarStyle. Cette opération Style définit des propriétés supplémentaires et utilise la BaseResourceKey propriété pour référencer searchBarStyle. L’extension DynamicResource de balisage n’est pas obligatoire, car tealSearchBarStyle elle ne change pas, à l’exception du Style dont elle dérive. Par conséquent, tealSearchBarStyle conserve un lien vers searchBarStyle et est modifié lorsque le style de base change.

Dans le fichier code-behind, le constructeur crée une ResourceDictionary entrée avec la clé searchBarStyle, comme dans l’exemple précédent qui a montré les styles dynamiques. Lorsque le OnButtonClicked gestionnaire d’événements est exécuté, searchBarStyle bascule entre blueSearchBarStyle et greenSearchBarStyle. Cela donne l’affichage illustré dans les captures d’écran suivantes :

Exemple d’héritage de style dynamique bleuExemple d’héritage de style dynamique vert

L’exemple de code suivant illustre la page équivalente en C# :

public class DynamicStylesInheritancePageCS : ContentPage
{
    bool originalStyle = true;

    public DynamicStylesInheritancePageCS ()
    {
        ...
        var baseStyle = new Style (typeof(View)) {
            ...
        };
        var blueSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        var greenSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        var tealSearchBarStyle = new Style (typeof(SearchBar)) {
            BaseResourceKey = "searchBarStyle",
            ...
        };
        ...
        Resources = new ResourceDictionary ();
        Resources.Add ("blueSearchBarStyle", blueSearchBarStyle);
        Resources.Add ("greenSearchBarStyle", greenSearchBarStyle);
        Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];

        Content = new StackLayout {
            Children = {
                new SearchBar { Text = "These SearchBar controls", Style = tealSearchBarStyle },
                ...
            }
        };
    }
    ...
}

le tealSearchBarStyle est affecté directement à la Style propriété des SearchBar instances. Cette opération Style définit des propriétés supplémentaires et utilise la BaseResourceKey propriété pour référencer searchBarStyle. La SetDynamicResource méthode n’est pas obligatoire ici, car tealSearchBarStyle elle ne change pas, à l’exception du Style dont elle dérive. Par conséquent, tealSearchBarStyle conserve un lien vers searchBarStyle et est modifié lorsque le style de base change.

Retrouvez d’autres vidéos Xamarin sur Channel 9 et YouTube.