Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Efeitos simplificam a personalização de um controle. Este artigo demonstra como criar um efeito que altera a cor da tela de fundo do controle Entry quando o controle obtém foco.
O processo para criar um efeito em cada projeto específico da plataforma é o seguinte:
- Crie uma subclasse da classe
PlatformEffect. - Substitua o método
OnAttachede escreva a lógica para personalizar o controle. - Substitua o método
OnDetachede escreva a lógica para limpar a personalização do controle se necessário. - Adicione um atributo
ResolutionGroupNameà classe do efeito. Esse atributo define um namespace para os efeitos que abrange toda a empresa, evitando conflitos com outros efeitos de mesmo nome. Observe que esse atributo só pode ser aplicado uma vez por projeto. - Adicione um atributo
ExportEffectà classe do efeito. Esse atributo registra o efeito com uma ID exclusiva que é usada por Xamarin.Forms, juntamente com o nome do grupo, para localizar o efeito antes de aplicá-lo a um controle. O atributo utiliza dois parâmetros – o nome do tipo de efeito e uma cadeia de caracteres exclusiva que será usada para localizar o efeito antes de aplicá-lo a um controle.
O efeito, em seguida, poderá ser consumido sendo anexado ao controle apropriado.
Observação
O fornecimento de um efeito em cada projeto de plataforma é opcional. Tentar usar um efeito quando não há um efeito registrado retornará um valor não nulo que não faz nada.
O aplicativo de exemplo demonstra um FocusEffect que altera a cor da tela de fundo de um controle quando ele obtém o foco. O seguinte diagrama ilustra as responsabilidades de cada projeto no aplicativo de exemplo, bem como as relações entre elas:

Um controle Entry no HomePage é personalizado pela classe FocusEffect em cada projeto específico da plataforma. Cada classe FocusEffect é derivada da classe PlatformEffect de cada plataforma. Isso faz com que o controle Entry seja renderizado com uma cor da tela de fundo específica da plataforma, que muda quando o controle obtém foco, conforme mostrado nas capturas de tela seguir:


Criando o efeito em cada plataforma
As seções a seguir abordam a implementação da classe FocusEffect específica da plataforma.
Projeto do iOS
O exemplo de código a seguir mostra a implementação de FocusEffect para o projeto do iOS:
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly:ResolutionGroupName ("MyCompany")]
[assembly:ExportEffect (typeof(EffectsDemo.iOS.FocusEffect), nameof(EffectsDemo.iOS.FocusEffect))]
namespace EffectsDemo.iOS
{
public class FocusEffect : PlatformEffect
{
UIColor backgroundColor;
protected override void OnAttached ()
{
try {
Control.BackgroundColor = backgroundColor = UIColor.FromRGB (204, 153, 255);
} catch (Exception ex) {
Console.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached ()
{
}
protected override void OnElementPropertyChanged (PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged (args);
try {
if (args.PropertyName == "IsFocused") {
if (Control.BackgroundColor == backgroundColor) {
Control.BackgroundColor = UIColor.White;
} else {
Control.BackgroundColor = backgroundColor;
}
}
} catch (Exception ex) {
Console.WriteLine ("Cannot set property on attached control. Error: ", ex.Message);
}
}
}
}
O método OnAttached define a propriedade BackgroundColor do controle como roxo claro com o método UIColor.FromRGB e também armazena essa cor em um campo. Essa funcionalidade é encapsulada em um bloco try/catch caso o controle a que o efeito está anexado não tenha uma propriedade de BackgroundColor. Nenhuma implementação é fornecida pelo método OnDetached porque nenhuma limpeza é necessária.
A OnElementPropertyChanged substituição responde às alterações de propriedade associável no Xamarin.Forms controle. Quando a propriedade IsFocused é alterada, a propriedade BackgroundColor do controle será alterada para branco se o controle estiver em foco, caso contrário, é alterada para roxo claro. Essa funcionalidade é encapsulada em um bloco try/catch caso o controle a que o efeito está anexado não tenha uma propriedade de BackgroundColor.
Projeto do Android
O exemplo de código a seguir mostra a implementação de FocusEffect para o projeto do Android:
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ResolutionGroupName("MyCompany")]
[assembly: ExportEffect(typeof(EffectsDemo.Droid.FocusEffect), nameof(EffectsDemo.Droid.FocusEffect))]
namespace EffectsDemo.Droid
{
public class FocusEffect : PlatformEffect
{
Android.Graphics.Color originalBackgroundColor = new Android.Graphics.Color(0, 0, 0, 0);
Android.Graphics.Color backgroundColor;
protected override void OnAttached()
{
try
{
backgroundColor = Android.Graphics.Color.LightGreen;
Control.SetBackgroundColor(backgroundColor);
}
catch (Exception ex)
{
Console.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached()
{
}
protected override void OnElementPropertyChanged(System.ComponentModel.PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged(args);
try
{
if (args.PropertyName == "IsFocused")
{
if (((Android.Graphics.Drawables.ColorDrawable)Control.Background).Color == backgroundColor)
{
Control.SetBackgroundColor(originalBackgroundColor);
}
else
{
Control.SetBackgroundColor(backgroundColor);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
}
}
O método OnAttached chama o método SetBackgroundColor para definir a cor da tela de fundo do controle como verde claro e também armazena essa cor em um campo. Essa funcionalidade é encapsulada em um bloco try/catch caso o controle a que o efeito está anexado não tenha uma propriedade de SetBackgroundColor. Nenhuma implementação é fornecida pelo método OnDetached porque nenhuma limpeza é necessária.
A OnElementPropertyChanged substituição responde às alterações de propriedade associável no Xamarin.Forms controle. Quando a propriedade IsFocused é alterada, a cor da tela de fundo do controle será alterada para branco se o controle estiver em foco, caso contrário, é alterada para verde claro. Essa funcionalidade é encapsulada em um bloco try/catch caso o controle a que o efeito está anexado não tenha uma propriedade de BackgroundColor.
Projetos da Plataforma Universal do Windows
O exemplo de código a seguir mostra a implementação de FocusEffect para projetos da UWP (Plataforma Universal do Windows):
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
[assembly: ResolutionGroupName("MyCompany")]
[assembly: ExportEffect(typeof(EffectsDemo.UWP.FocusEffect), nameof(EffectsDemo.UWP.FocusEffect))]
namespace EffectsDemo.UWP
{
public class FocusEffect : PlatformEffect
{
protected override void OnAttached()
{
try
{
(Control as Windows.UI.Xaml.Controls.Control).Background = new SolidColorBrush(Colors.Cyan);
(Control as FormsTextBox).BackgroundFocusBrush = new SolidColorBrush(Colors.White);
}
catch (Exception ex)
{
Debug.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached()
{
}
}
}
O método OnAttached define a propriedade Background do controle como ciano e define a propriedade BackgroundFocusBrush como branco. Essa funcionalidade é encapsulada em um bloco try/catch caso o controle a que o efeito está anexado não tenha essas propriedades. Nenhuma implementação é fornecida pelo método OnDetached porque nenhuma limpeza é necessária.
Consumindo o efeito
O processo para consumir um efeito de uma biblioteca .NET Standard ou de um Xamarin.Forms projeto de Biblioteca Compartilhada é o seguinte:
- Declare um controle que será personalizado pelo efeito.
- Anexe o efeito ao controle adicionando-o à coleção
Effectsdo controle.
Observação
Uma instância de efeito pode ser anexada somente a um único controle. Portanto, um efeito deve ser resolvido duas vezes para usá-lo em dois controles.
Consumindo o efeito em XAML
O exemplo de código XAML abaixo mostra um controle Entry ao qual o FocusEffect está anexado:
<Entry Text="Effect attached to an Entry" ...>
<Entry.Effects>
<local:FocusEffect />
</Entry.Effects>
...
</Entry>
A classe FocusEffect na biblioteca do .NET Standard dá suporte ao consumo do efeito em XAML e é mostrado no exemplo de código a seguir:
public class FocusEffect : RoutingEffect
{
public FocusEffect () : base ($"MyCompany.{nameof(FocusEffect)}")
{
}
}
A classe FocusEffect cria subclasses da classe RoutingEffect, que representa um efeito independente de plataforma que encapsula um efeito interno, que é geralmente é específico da plataforma. A classe FocusEffect chama o construtor da classe base, passando um parâmetro composto por uma concatenação do nome do grupo de resolução (especificado usando o atributo ResolutionGroupName na classe do efeito) e pela ID exclusiva que foi especificada usando o atributo ExportEffect na classe do efeito. Portanto, quando o Entry é inicializado em runtime, uma nova instância do MyCompany.FocusEffect é adicionada à coleção Effects do controle.
Efeitos também podem ser anexados a controles usando um comportamento ou usando propriedades anexadas. Para obter mais informações sobre como anexar um efeito a um controle usando um comportamento, confira EffectBehavior reutilizável. Para obter mais informações sobre como anexar um efeito a um controle usando propriedades anexadas, confira Passar parâmetros para um efeito.
Consumindo o efeito em C#
O Entry equivalente em C# é mostrado no exemplo de código a seguir:
var entry = new Entry {
Text = "Effect attached to an Entry",
...
};
O FocusEffect é anexado à instância de Entry adicionando o efeito à coleção Effects do controle, conforme demonstrado no exemplo de código a seguir:
public HomePageCS ()
{
...
entry.Effects.Add (Effect.Resolve ($"MyCompany.{nameof(FocusEffect)}"));
...
}
O Effect.Resolve retorna um Effect para o nome especificado, que é uma concatenação do nome do grupo de resolução (especificado usando o atributo ResolutionGroupName na classe do efeito) e pela ID exclusiva que foi especificada usando o atributo ExportEffect na classe do efeito. Se uma plataforma não fornecer o efeito, o método Effect.Resolve retornará um valor não null.
Resumo
Este artigo demonstrou como criar um efeito que altera a cor da tela de fundo do controle Entry quando o controle obtém foco.