Estilos dinâmicos em Xamarin.Forms
Os estilos não respondem a alterações de propriedade e permanecem inalterados durante a duração de um aplicativo. Por exemplo, depois de atribuir um Style a um elemento visual, se uma das instâncias Setter for modificada, removida ou uma nova instância Setter adicionada, as alterações não serão aplicadas ao elemento visual. No entanto, os aplicativos podem responder a alterações de estilo dinamicamente em runtime usando recursos dinâmicos.
A DynamicResource
extensão de marcação é semelhante à StaticResource
extensão de marcação em que ambos usam uma chave de dicionário para buscar um valor de um ResourceDictionary
. No entanto, enquanto o StaticResource
executa uma única pesquisa de dicionário, o DynamicResource
mantém um link para a chave do dicionário. Portanto, se a entrada de dicionário associada à chave for substituída, a alteração será aplicada ao elemento visual. Isso permite que as alterações de estilo de runtime sejam feitas em um aplicativo.
O exemplo de código a seguir demonstra estilos dinâmicos em uma 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>
As SearchBar
instâncias usam a DynamicResource
extensão de marcação para fazer referência a um Style
chamado searchBarStyle
, que não está definido no XAML. No entanto, como as Style
propriedades das SearchBar
instâncias são definidas usando um DynamicResource
, a chave de dicionário ausente não resulta na geração de uma exceção.
Em vez disso, no arquivo code-behind, o construtor cria uma ResourceDictionary
entrada com a chave searchBarStyle
, conforme mostrado no exemplo de código a seguir:
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;
}
}
}
Quando o OnButtonClicked
manipulador de eventos for executado, searchBarStyle
alternará entre blueSearchBarStyle
e greenSearchBarStyle
. Isso resulta na aparência mostrada nas capturas de tela seguir:
O exemplo de código a seguir demonstra a página equivalente em 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 }
};
}
...
}
Em C#, as SearchBar
instâncias usam o SetDynamicResource
método para referenciar searchBarStyle
. O OnButtonClicked
código do manipulador de eventos é idêntico ao exemplo de XAML e, quando executado, searchBarStyle
alternará entre blueSearchBarStyle
e greenSearchBarStyle
.
Herança de estilo dinâmico
Derivar um estilo de um estilo dinâmico não pode ser obtido usando a Style.BasedOn
propriedade . Em vez disso, a Style
classe inclui a BaseResourceKey
propriedade , que pode ser definida como uma chave de dicionário cujo valor pode ser alterado dinamicamente.
O exemplo de código a seguir demonstra a herança de estilo dinâmico em uma 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>
As SearchBar
instâncias usam a StaticResource
extensão de marcação para fazer referência a um Style
nomeado tealSearchBarStyle
. Isso Style
define algumas propriedades adicionais e usa a BaseResourceKey
propriedade para referenciar searchBarStyle
. A DynamicResource
extensão de marcação não é necessária porque tealSearchBarStyle
não será alterada, exceto pela Style
derivada dela. Portanto, tealSearchBarStyle
mantém um link para searchBarStyle
e é alterado quando o estilo base é alterado.
No arquivo code-behind, o construtor cria uma ResourceDictionary
entrada com a chave searchBarStyle
, de acordo com o exemplo anterior que demonstrou estilos dinâmicos. Quando o OnButtonClicked
manipulador de eventos for executado, searchBarStyle
alternará entre blueSearchBarStyle
e greenSearchBarStyle
. Isso resulta na aparência mostrada nas capturas de tela seguir:
O exemplo de código a seguir demonstra a página equivalente em 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 },
...
}
};
}
...
}
O tealSearchBarStyle
é atribuído diretamente à Style
propriedade das SearchBar
instâncias. Isso Style
define algumas propriedades adicionais e usa a BaseResourceKey
propriedade para referenciar searchBarStyle
. O SetDynamicResource
método não é necessário aqui porque tealSearchBarStyle
não será alterado, exceto pelo Style
do qual ele deriva. Portanto, tealSearchBarStyle
mantém um link para searchBarStyle
e é alterado quando o estilo base é alterado.
Links relacionados
- Extensões de marcação XAML
- Estilos dinâmicos (exemplo)
- Trabalhando com estilos (exemplo)
- ResourceDictionary
- Estilo
- Setter
Vídeo relacionado
Encontre mais vídeos sobre o Xamarin no Channel 9 e no YouTube.