Estilos dinámicos en Xamarin.Forms
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 , DynamicResource
la 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:
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 searchBarStyle
a . 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 searchBarStyle
a . 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:
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 searchBarStyle
a . 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.
Vínculos relacionados
- Extensiones de marcado XAML
- Estilos dinámicos (ejemplo)
- Trabajar con estilos (ejemplo)
- ResourceDictionary
- Estilo
- Setter