Propriedades Anexadas

As propriedades anexadas permitem que um objeto atribua um valor a uma propriedade que sua própria classe não define. Por exemplo, os elementos filhos podem usar propriedades anexadas para informar ao elemento pai como eles devem ser apresentados na interface do usuário. O Grid controle permite que a linha e a coluna de um filho sejam especificadas definindo as Grid.Row propriedades e Grid.Column anexadas. Grid.Row e Grid.Column são propriedades anexadas porque são definidas em elementos que são filhos de um Grid, e não no próprio Grid.

As propriedades associáveis devem ser implementadas como propriedades anexadas nos seguintes cenários:

  • Quando houver necessidade de ter um mecanismo de definição de propriedade disponível para classes diferentes da classe definidora.
  • Quando a classe representa um serviço que precisa ser facilmente integrado a outras classes.

Para obter mais informações sobre propriedades associáveis, consulte Propriedades associáveis.

Criar uma propriedade anexada

O processo de criação de uma propriedade anexada é o seguinte:

  1. Crie uma instância BindableProperty com uma das sobrecargas do método CreateAttached.
  2. Forneça os métodos staticGetPropertyName e SetPropertyName como acessadores para a propriedade anexada.

Crie uma propriedade

Ao criar uma propriedade anexada para uso em outros tipos, a classe em que a propriedade é criada não precisa derivar de BindableObject. No entanto, a propriedade de destino para acessadores deve ser, ou derivar, de BindableObject.

Uma propriedade anexada pode ser criada declarando uma propriedade public static readonly do tipo BindableProperty. A propriedade associável deve ser definida como o valor retornado de uma das sobrecargas de método BindableProperty.CreateAttached. A declaração deve estar dentro do corpo da classe proprietária, mas fora de qualquer definição de membro.

Importante

A convenção de nomenclatura para propriedades anexadas é que o identificador da propriedade anexada deve corresponder ao nome da propriedade especificado no método CreateAttached, com "Propriedade" anexado a ele.

O código a seguir mostra um exemplo de uma propriedade anexada:

public static readonly BindableProperty HasShadowProperty =
  BindableProperty.CreateAttached ("HasShadow", typeof(bool), typeof(ShadowEffect), false);

Isso cria uma propriedade anexada chamada HasShadowProperty, do tipo bool. A propriedade pertence à classe ShadowEffect e tem um valor padrão de false.

Para obter mais informações sobre a criação de propriedades associáveis, incluindo parâmetros que podem ser especificados durante a criação, consulte Criar uma propriedade associável.

Crie acessadores

Os métodos estáticos GetPropertyName e SetPropertyName são necessários como acessadores da propriedade anexada; caso contrário, o sistema de propriedades não poderá usar a propriedade anexada. O acessador GetPropertyName deve estar em conformidade com a seguinte assinatura:

public static valueType GetPropertyName(BindableObject target)

O acessador GetPropertyName deve retornar o valor contido no campo BindableProperty correspondente da propriedade anexada. Isso pode ser obtido chamando o método GetValue, passando o identificador da propriedade associável no qual se deseja obter o valor e, em seguida, convertendo o valor resultante para o tipo necessário.

O acessador SetPropertyName deve estar em conformidade com a seguinte assinatura:

public static void SetPropertyName(BindableObject target, valueType value)

O acessador SetPropertyName deve definir o valor do campo BindableProperty correspondente da propriedade anexada. Isso pode ser feito chamando o método SetValue, passando o identificador da propriedade associável na qual será definido o valor e o valor a ser definido.

Para ambos os acessadores, o objeto de destino deve ser, ou derivar, de BindableObject.

O exemplo de código a seguir mostra os acessadores da propriedade anexada HasShadow:

public static bool GetHasShadow (BindableObject view)
{
  return (bool)view.GetValue (HasShadowProperty);
}

public static void SetHasShadow (BindableObject view, bool value)
{
  view.SetValue (HasShadowProperty, value);
}

Consumir uma propriedade anexada

Após a criação de uma propriedade anexada, ela pode ser consumida a partir do XAML ou do código. No XAML, isso é feito declarando um namespace com um prefixo, com a declaração do namespace indicando o nome do namespace do Common Language Runtime (CLR) e, opcionalmente, um nome de assembly. Para obter mais informações, confira Namespaces de XAML.

O exemplo de código a seguir demonstra um namespace XAML para um tipo personalizado que contém uma propriedade anexada, que é definida no mesmo assembly que o código do aplicativo que está referenciando o tipo personalizado:

<ContentPage ... xmlns:local="clr-namespace:EffectsDemo" ...>
  ...
</ContentPage>

A declaração de namespace é usada ao definir a propriedade anexada em um controle específico, conforme demonstrado no seguinte exemplo de código XAML:

<Label Text="Label Shadow Effect" local:ShadowEffect.HasShadow="true" />

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

var label = new Label { Text = "Label Shadow Effect" };
ShadowEffect.SetHasShadow (label, true);

Consumir uma propriedade anexada com um estilo

As propriedades anexadas também podem ser adicionadas a um controle por um estilo. O exemplo de código XAML a seguir mostra um estilo explícito que usa a HasShadow propriedade anexada, que pode ser aplicada a Label controles:

<Style x:Key="ShadowEffectStyle" TargetType="Label">
  <Style.Setters>
    <Setter Property="local:ShadowEffect.HasShadow" Value="true" />
  </Style.Setters>
</Style>

O Style pode ser aplicado a um Label definindo sua propriedade Style para a instância de Style usando a extensão de marcação StaticResource, conforme demonstrado no exemplo de código a seguir:

<Label Text="Label Shadow Effect" Style="{StaticResource ShadowEffectStyle}" />

Para mais informações sobre estilos, confira Estilos.

Cenários avançados

Ao criar uma propriedade anexada, há vários parâmetros opcionais que podem ser definidos para habilitar cenários avançados de propriedade anexada. Isso inclui a detecção de alterações de propriedade, a validação de valores de propriedade e a coerção de valores de propriedade. Para obter mais informações, confira Cenários avançados.