Comportamentos anexados

Comportamentos anexados são classes estáticas com uma ou mais propriedades anexadas. Este artigo demonstra como criar e consumir comportamentos anexados.

Visão geral

Uma propriedade anexada é um tipo especial de propriedade associável. Elas são definidas em uma classe, mas são anexadas a outros objetos e reconhecíveis no XAML como atributos que contêm uma classe e um nome de propriedade separados por um ponto.

Uma propriedade anexada pode definir um delegado propertyChanged que será executado quando o valor da propriedade for alterado, por exemplo, quando a propriedade for definida em um controle. Quando o delegado propertyChanged é executado, é passada a ele uma referência ao controle a que ele está sendo anexado, bem como parâmetros que contêm os valores antigo e novo da propriedade. Esse delegado pode ser usado para adicionar uma nova funcionalidade ao controle a que a propriedade está anexada manipulando a referência que é passada, da seguinte maneira:

  1. O delegado propertyChanged converte a referência do controle, que é recebida como um BindableObject, para o tipo de comportamento que o controle deve melhorar.
  2. O delegado propertyChanged modifica as propriedades do controle, chama os métodos do controle ou registra manipuladores de eventos para eventos expostos pelo controle, a fim de implementar a funcionalidade do comportamento de núcleo.

Um problema com comportamentos anexados é que eles são definidos em uma classe static, com propriedades static e métodos. Isso dificulta a criação de comportamentos anexados com estado. Além disso, Xamarin.Forms os comportamentos substituíram os comportamentos apegados como a abordagem preferida para a construção do comportamento. Para obter mais informações sobre Xamarin.Forms comportamentos, consulte Xamarin.Forms Comportamentos.

Criando um comportamento anexado

O aplicativo de exemplo demonstra um NumericValidationBehavior, que destaca o valor inserido pelo usuário em um controle Entry em vermelho, caso ele não seja um double. O comportamento é mostrado no exemplo de código a seguir:

public static class NumericValidationBehavior
{
    public static readonly BindableProperty AttachBehaviorProperty =
        BindableProperty.CreateAttached (
            "AttachBehavior",
            typeof(bool),
            typeof(NumericValidationBehavior),
            false,
            propertyChanged:OnAttachBehaviorChanged);

    public static bool GetAttachBehavior (BindableObject view)
    {
        return (bool)view.GetValue (AttachBehaviorProperty);
    }

    public static void SetAttachBehavior (BindableObject view, bool value)
    {
        view.SetValue (AttachBehaviorProperty, value);
    }

    static void OnAttachBehaviorChanged (BindableObject view, object oldValue, object newValue)
    {
        var entry = view as Entry;
        if (entry == null) {
            return;
        }

        bool attachBehavior = (bool)newValue;
        if (attachBehavior) {
            entry.TextChanged += OnEntryTextChanged;
        } else {
            entry.TextChanged -= OnEntryTextChanged;
        }
    }

    static void OnEntryTextChanged (object sender, TextChangedEventArgs args)
    {
        double result;
        bool isValid = double.TryParse (args.NewTextValue, out result);
        ((Entry)sender).TextColor = isValid ? Color.Default : Color.Red;
    }
}

A classe NumericValidationBehavior contém uma propriedade anexada chamada AttachBehavior, com um getter e setter static, que controla a adição ou remoção do comportamento do controle a que ele será anexado. Essa propriedade anexada registra o método OnAttachBehaviorChanged que será executado quando o valor da propriedade for alterado. Esse método registra ou cancela o registra de um manipulador de eventos para o evento TextChanged, com base no valor da propriedade anexada AttachBehavior. A funcionalidade núcleo do comportamento é fornecida pelo método OnEntryTextChanged, que analisa o valor inserido no Entry pelo usuário e define a propriedade TextColor como vermelha caso o valor não seja um double.

Consumindo um comportamento anexado

A classe NumericValidationBehavior pode ser consumida adicionando a propriedade anexada AttachBehavior a um controle Entry, conforme demonstrado no exemplo de código XAML a seguir:

<ContentPage ... xmlns:local="clr-namespace:WorkingWithBehaviors;assembly=WorkingWithBehaviors" ...>
    ...
    <Entry Placeholder="Enter a System.Double" local:NumericValidationBehavior.AttachBehavior="true" />
    ...
</ContentPage>

O Entry equivalente em C# é mostrado no exemplo de código a seguir:

var entry = new Entry { Placeholder = "Enter a System.Double" };
NumericValidationBehavior.SetAttachBehavior (entry, true);

Em runtime, o comportamento responderá à interação com o controle, de acordo com a implementação do comportamento. As capturas de tela a seguir demonstram o comportamento anexado respondendo a uma entrada inválida:

Aplicativo de Exemplo com Comportamento Anexado

Observação

Comportamentos anexados são escritos para um tipo de controle específico (ou uma superclasse que pode ser aplicada a muitos controles) e só devem ser adicionados a um controle compatível. Tentar anexar um comportamento a um controle incompatível resultará em um comportamento desconhecido e depende da implementação do comportamento.

Removendo um comportamento anexado de um controle

A classe NumericValidationBehavior pode ser removida de um controle definindo a propriedade anexada AttachBehavior como false, conforme demonstrado no exemplo de código XAML a seguir:

<Entry Placeholder="Enter a System.Double" local:NumericValidationBehavior.AttachBehavior="false" />

O Entry equivalente em C# é mostrado no exemplo de código a seguir:

var entry = new Entry { Placeholder = "Enter a System.Double" };
NumericValidationBehavior.SetAttachBehavior (entry, false);

No runtime, o método OnAttachBehaviorChanged será executado quando o valor da propriedade anexada AttachBehavior for definida como false. O método OnAttachBehaviorChanged, então, cancelará o registro do manipulador de eventos para o evento TextChanged, garantindo que o comportamento não seja executado conforme o usuário interagir com o controle.

Resumo

Este artigo demonstrou como criar e consumir comportamentos anexados. Comportamentos anexados são classes static com uma ou mais propriedades anexadas.