Estilos dinámicos en Xamarin.Forms

Descargar ejemploDescargar el ejemplo

Los estilos no responden a los cambios de propiedad y permanecen sin cambios durante la duración de una aplicación. Por ejemplo, después de asignar un estilo a un elemento visual, si una de las instancias de Setter se modifica, quita o se agrega una nueva instancia de Establecedor, los cambios no se aplicarán al elemento visual. Sin embargo, las aplicaciones pueden responder a cambios de estilo dinámicamente en tiempo de ejecución mediante recursos dinámicos.

La DynamicResource extensión de marcado es similar a la StaticResource extensión de marcado en que ambas usan una clave de diccionario para capturar un valor de .ResourceDictionary Sin embargo, mientras StaticResource realiza una búsqueda de diccionario único, DynamicResource mantiene un vínculo a la clave del diccionario. Por lo tanto, si se reemplaza la entrada del diccionario asociada a la clave, el cambio se aplica al elemento visual. Esto permite realizar cambios de estilo en tiempo de ejecución en una aplicación.

En el ejemplo de código siguiente se muestran estilos dinámicos en una página 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>

Las SearchBar instancias usan la DynamicResource extensión de marcado para hacer referencia a un elemento Style con nombre searchBarStyle, que no está definido en el XAML. Sin embargo, dado que las Style propiedades de las SearchBar instancias se establecen mediante , DynamicResourcela clave de diccionario que falta no produce una excepción.

En su lugar, en el archivo de código subyacente, el constructor crea una ResourceDictionary entrada con la clave searchBarStyle, como se muestra en el ejemplo de código siguiente:

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

Cuando se ejecute el OnButtonClicked controlador de eventos, searchBarStyle cambiará entre blueSearchBarStyle y greenSearchBarStyle. El resultado es el aspecto que se muestra en las capturas de pantalla siguientes:

Ejemplo de estilo dinámicoazul Ejemplo de estilo dinámico verde

En el ejemplo de código siguiente se muestra la página equivalente 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#, las SearchBar instancias usan el SetDynamicResource método para hacer referencia searchBarStylea . El OnButtonClicked código del controlador de eventos es idéntico al ejemplo XAML y, cuando se ejecuta, searchBarStyle cambiará entre blueSearchBarStyle y greenSearchBarStyle.

Herencia de estilo dinámico

La derivación de un estilo de un estilo dinámico no se puede lograr mediante la Style.BasedOn propiedad . En su lugar, la Style clase incluye la BaseResourceKey propiedad , que se puede establecer en una clave de diccionario cuyo valor podría cambiar dinámicamente.

En el ejemplo de código siguiente se muestra la herencia de estilo dinámico en una página 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>

Las SearchBar instancias usan la StaticResource extensión de marcado para hacer referencia a un objeto Style denominado tealSearchBarStyle. Esto Style establece algunas propiedades adicionales y usa la BaseResourceKey propiedad para hacer referencia searchBarStylea . La DynamicResource extensión de marcado no es necesaria porque tealSearchBarStyle no cambiará, excepto para la Style que deriva. Por lo tanto, tealSearchBarStyle mantiene un vínculo a searchBarStyle y se modifica cuando cambia el estilo base.

En el archivo de código subyacente, el constructor crea una ResourceDictionary entrada con la clave searchBarStyle, según el ejemplo anterior que mostró estilos dinámicos. Cuando se ejecute el OnButtonClicked controlador de eventos, searchBarStyle cambiará entre blueSearchBarStyle y greenSearchBarStyle. El resultado es el aspecto que se muestra en las capturas de pantalla siguientes:

Ejemplo de herencia de estilodinámico azul Ejemplo de herencia de estilo dinámico verde

En el ejemplo de código siguiente se muestra la página equivalente 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 },
                ...
            }
        };
    }
    ...
}

tealSearchBarStyle se asigna directamente a la Style propiedad de las SearchBar instancias. Esto Style establece algunas propiedades adicionales y usa la BaseResourceKey propiedad para hacer referencia searchBarStylea . El SetDynamicResource método no es necesario aquí porque tealSearchBarStyle no cambiará, excepto el Style elemento del que deriva. Por lo tanto, tealSearchBarStyle mantiene un vínculo a searchBarStyle y se modifica cuando cambia el estilo base.

Encuentre más vídeos de Xamarin en Channel 9 y YouTube.