Share via


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 do Setter for modificada, removida ou uma nova instância do 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 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 ResourceDictionaryarquivo . No entanto, enquanto o StaticResource executa uma única pesquisa de dicionário, o DynamicResource mantém um link para a chave de 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 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 DynamicResource extensão de marcação para fazer referência a um Style nome searchBarStyle, que não está definido no XAML. No entanto, como as StyleSearchBar propriedades das instâncias são definidas usando um DynamicResource, a chave de dicionário ausente não resulta em uma exceção sendo lançada.

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:

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

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 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 StyletealSearchBarStylearquivo . Isso Style define algumas propriedades adicionais e usa a BaseResourceKey propriedade para fazer referência searchBarStylea . A DynamicResource extensão de marcação não é necessária porque tealSearchBarStyle não será alterada, exceto para o Style que deriva. Portanto, tealSearchBarStyle mantém um link para searchBarStyle e é alterado quando o estilo base muda.

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 OnButtonClicked manipulador de 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 ele deriva. Portanto, tealSearchBarStyle mantém um link para searchBarStyle e é alterado quando o estilo base muda.

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