Estilos dinámicos en Xamarin.Forms

Ejemplo de descarga Descarga del 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 se modifica, quita o agrega una nueva instancia de Setter, los cambios no se aplicarán al elemento visual. Sin embargo, las aplicaciones pueden responder a los cambios de estilo dinámicamente en tiempo de ejecución mediante recursos dinámicos.

La extensión de marcado es similar a la extensión de marcado en que usan una clave de diccionario para DynamicResource capturar un valor de StaticResourceResourceDictionary . Sin embargo, mientras realiza una búsqueda de diccionario única, mantiene StaticResource un vínculo a la clave del DynamicResource diccionario. Por lo tanto, si se reemplaza la entrada de 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 los 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 de usan la extensión de marcado para hacer referencia a un denominado , que no DynamicResource está definido en StylesearchBarStyle xaml. Sin embargo, dado que las propiedades Xamarin_Forms _NavigableElement_Style" data-linktype="absolute-path">de las instancias se establecen mediante , la clave de diccionario que falta no produce una StyleSearchBarDynamicResource excepción.

En su lugar, en el archivo de código subyacente, el constructor crea una entrada con la clave , como ResourceDictionary se muestra en el ejemplo de código searchBarStyle 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 OnButtonClicked ejecuta el controlador de eventos, cambia entre y searchBarStyleblueSearchBarStylegreenSearchBarStyle . 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 de usan el método para hacer referencia a SetDynamicResourcesearchBarStyle . El OnButtonClicked código del controlador de eventos es idéntico al ejemplo XAML y, cuando se ejecuta, cambia entre y searchBarStyleblueSearchBarStylegreenSearchBarStyle .

Herencia de estilo dinámico

La derivación de un estilo a partir de un estilo dinámico no se puede lograr mediante la propiedad Xamarin_Forms _Style_BasedOn" data-linktype="absolute-path">. Style.BasedOn En su lugar, la clase incluye la propiedad Style Xamarin_Forms Style _Style_BaseResourceKey" data-linktype="absolute-path">, que se puede establecer en una clave de diccionario cuyo valor podría cambiar BaseResourceKey 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 de usan la extensión de marcado para hacer referencia a un denominado StaticResourceStyletealSearchBarStyle . Esto establece algunas propiedades adicionales y usa la propiedad StyleStyle Xamarin_Forms _Style_BaseResourceKey" data-linktype="absolute-path">BaseResourceKey para hacer referencia a searchBarStyle . La DynamicResource extensión de marcado no es necesaria porque no cambiará, excepto para el que tealSearchBarStyleStyle deriva. Por lo tealSearchBarStyle tanto, 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 entrada con la clave , según el ejemplo anterior que muestra estilos ResourceDictionarysearchBarStyle dinámicos. Cuando se OnButtonClicked ejecuta el controlador de eventos, cambia entre y searchBarStyleblueSearchBarStylegreenSearchBarStyle . El resultado es el aspecto que se muestra en las capturas de pantalla siguientes:

Ejemplo de herencia de estilo dinámicoazul: 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 },
                ...
            }
        };
    }
    ...
}

se tealSearchBarStyle asigna directamente a la Xamarin_Forms tealSearchBarStyle _NavigableElement_Style" data-linktype="absolute-path">propiedad de las StyleSearchBar instancias. Esto establece algunas propiedades adicionales y usa la propiedad StyleStyle Xamarin_Forms _Style_BaseResourceKey" data-linktype="absolute-path">BaseResourceKey para searchBarStyle hacer referencia a . El método no es necesario aquí porque no cambiará, excepto SetDynamicResource para el que tealSearchBarStyleStyle deriva. Por lo tealSearchBarStyle tanto, 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.