Estilos Implícitos
Cada entrada em um "ResourceDictionary" requer uma chave de dicionário. Este é um fato indiscutível. Se você tentar passar uma chave nula para o método "Add" de um objeto "ResourceDictionary", você vai disparar uma exceção "Argument-NullException".
No entanto, há um caso especial aonde um programador não é necessário para fornecer essa chave dicionário e essa chave é em vez disso gerada automaticamente.
Este caso especial é para um objeto "Style" adicionado a um "ResourceDictionary" sem uma configuração "x: Key". O "ResourceDictionary" gera uma chave com base no "Targettype", que é sempre necessária. (Uma breve exploração revelará que esta chave dicionário especial é o nome completo associado com o "TargetType" do estilo. Para um TargetType Button, por exemplo, a chave de dicionário é "Xamarin.Forms.Button". Mas você não precisa saber disso.)
Você também pode adicionar um estilo a um "ResourceDictionary" sem uma chave de dicionário em código: uma sobrecarga do método "Add" aceita um argumento do tipo estilo, mas não exige qualquer outra coisa.
Um objeto de estilo em um "ResourceDictionary" que tem uma dessas chaves geradas é conhecido como um estilo implícito, e a chave de dicionário gerada é muito especial. Você não pode se referir a essa chave usando diretamente "StaticResource". No entanto, se um elemento dentro do âmbito da "ResourceDictionary" tem o mesmo tipo que a chave do dicionário, e se esse elemento não tiver sua propriedade de estilo explicitamente definida para outro objeto "Style," então este estilo implícito é aplicado automaticamente.
O seguinte "XAML" do projeto "ImplicitStyle" demonstra isso. É o mesmo que o arquivo "XAML" "BasicStyle", exceto que o estilo não tem configuração "x : Key" e as propriedades de estilo nos botões não são definidas usando "StaticResource":
Apesar da ausência de qualquer ligação explícita entre os botões e o estilo, o estilo é definitivamente aplicado:
Um estilo implícito é aplicado somente quando a classe do elemento coincide com o "TargetType" do estilo exatamente. Se você incluir um elemento que deriva de "Button" no "StackLayout", não terá o estilo aplicado.
Você pode usar as configurações de propriedade locais para substituir propriedades definidas através do estilo implícito, assim como você pode substituir configurações de propriedade em um estilo definido com "StaticResource".
Você vai achar estilos implícitos um recurso muito poderoso e extremamente útil. Sempre que você tem várias "Views" do mesmo tipo e você determinar que você quer que todas elas tenham uma configuração de propriedade idêntica ou dois, é muito fácil de definir rapidamente um estilo implícito. Você não tem que tocar os próprios elementos.
No entanto, com tanto poder pelo menos alguma responsabilidade o programador tem. Porque nenhum estilo é referência nos próprios elementos, o que pode ser confuso quando examinado o "XAML" para determinar se alguns elementos são estilizados ou não. Por vezes, a aparência de uma página indica que um estilo implícito é aplicado a alguns elementos, mas não é bastante óbvio onde o estilo implícito é definido. Se você então quiser mudar esse estilo implícito, você tem que procurar manualmente por ele na árvore visual.
Por esta razão, você deve definir estilos implícitos tão perto quanto possível dos elementos aos quais eles são aplicados. Se as "Views" que estão utilizando o estilo implícito estão em um determinado "StackLayout", em seguida, definia o estilo implícito na seção Recursos neste "StackLayout". Um comentário ou dois poderiam ajudar a evitar a confusão também.
Curiosamente, estilos implícitos têm uma restrição interna que pode persuadi-lo a mantê-los perto para os elementos aos quais são aplicados. Aqui está a restrição: Você pode derivar um estilo implícito de um estilo com uma chave de dicionário explícito, mas você não pode fazer o caminho inverso. Você não pode usar "BasedOn" para fazer referência a um estilo implícito.
Se você definir uma cadeia de estilos que utilizam "BasedOn" para derivar um do outro, o estilo implícito ( se houver) estará sempre no final da cadeia. Não será possível a existência de outras derivações.
Isto implica que você pode estruturar seus estilos com três tipos de hierarquias:
- A partir de estilos definidos sobre a Aplicação e "Page Down" para estilos definidos em "layouts" mais abaixo na árvore visual.
- A partir de estilos definidos para classes de base, tais como "VisualElement" e "View" para estilos definidos para classes específicas.
- A partir de estilos com chaves de dicionário explícitas para estilos implícitos.
Isto é demonstrado no projeto "StyleHierarchy", que utiliza um semelhante (mas de certa forma simplificado) conjunto de estilos como você viu no início do projeto "StyleInheritance". No entanto, esses estilos estão agora espalhados em mais de três seções de recursos.
Usando uma técnica que você viu no programa "ResourceTrees" no capítulo 10 , o projeto "StyleHierarchy" recebeu uma classe "App" baseada em "XAML". A classe "App.xaml" tem um "ResourceDictionary" contendo um estilo com apenas uma propriedade "Setter":
Em um aplicativo de várias páginas, este estilo seria usado em todo o aplicativo.
O arquivo "code-behind" da classe "App" chama o método InitializeComponent para processar o arquivo "XAML" e definir a propriedade "MainPage":
O arquivo "XAML" da classe de página define um estilo para a página inteira que deriva do estilo na classe "App" e, em seguida, dois estilos implícitos que derivam do estilo para a página. Observe que a propriedade de estilo da página está definida para o estilo definido na classe "App":
Os estilos implícitos são definidos como próximos aos elementos de destino quando possível.
Aqui está o resultado:
O incentivo para separar objetos de estilo em dicionários separados não faz muito sentido para pequenos programas como este, mas para programas maiores, torna-se tão importante ter uma hierarquia estruturada de definições de estilos quanto ter uma hierarquia estruturada de definições de classe.
As vezes você vai ter um estilo com uma chave de dicionário explícita (por exemplo, "myButtonStyle"), mas você vai querer que o mesmo estilo seja implícito também. Basta definir um estilo com base nessa chave com nenhuma tecla ou "setters" próprios: