Partilhar via


Estilos dinâmicos em Xamarin.Forms

Os estilos não respondem a alterações de propriedade e permanecem inalterados durante a aplicação Por exemplo, depois de atribuir um Style a um elemento visual, se uma das instâncias de Setter for modificada, removida ou uma nova instância de Setter for 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 tempo de execução usando recursos dinâmicos.

A extensão de marcação DynamicResource é semelhante à extensão de marcação StaticResource, pois ambas 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 do dicionário associada à chave for substituída, a alteração será aplicada ao elemento visual. Isso permite que alterações de estilo de tempo de execução 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 extensão de DynamicResource marcação para fazer referência a um Style , searchBarStylenomeado que não está definido no XAML. No entanto, como as Style SearchBar propriedades das 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 manipulador de OnButtonClicked eventos for executado, searchBarStyle alternará entre blueSearchBarStyle e greenSearchBarStyle. Isso resulta na aparência mostrada nas capturas de tela seguir:

Exemplo de estilo dinâmico azulExemplo de estilo dinâmico verde

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 fazer referência searchBarStylea . O OnButtonClicked código do manipulador de eventos é idêntico ao exemplo XAML e, quando executado, searchBarStyle alternará entre blueSearchBarStyle e greenSearchBarStyle.

Herança de estilo dinâmico

A derivação de um estilo de um estilo dinâmico não pode ser obtida usando a propriedade Style.BasedOn. Em vez disso, a classe Style inclui a propriedade BaseResourceKey, 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 .tealSearchBarStyle Este Style define algumas propriedades adicionais e usa a propriedade BaseResourceKey para fazer referência a searchBarStyle. A extensão de marcação DynamicResource não é necessária porque tealSearchBarStyle não será alterada, exceto para a Style da qual deriva. Portanto, tealSearchBarStyle mantém um link e searchBarStyle é alterado quando o estilo base é alterado.

No arquivo code-behind, o construtor cria uma ResourceDictionary entrada com a chave searchBarStyle, conforme o exemplo anterior que demonstrou estilos dinâmicos. Quando o manipulador de OnButtonClicked eventos for executado, searchBarStyle alternará entre blueSearchBarStyle e greenSearchBarStyle. Isso resulta na aparência mostrada nas capturas de tela seguir:

Exemplo de herança de estilo dinâmico azulExemplo de herança de estilo dinâmico verde

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 fazer referência searchBarStylea . O SetDynamicResource método não é necessário aqui porque tealSearchBarStyle não será alterado, exceto pelo Style que deriva. Portanto, tealSearchBarStyle mantém um link e searchBarStyle é alterado quando o estilo base é alterado.

Encontre mais vídeos sobre o Xamarin no Channel 9 e no YouTube.