Attached Properties Overview

Uma propriedade anexada é um conceito definido por Extensible Application Markup Language (XAML). Uma propriedade anexada destina-se a ser usada como um tipo de propriedade global que é configurável em qualquer objeto. Em Windows Presentation Foundation (WPF), propriedades anexadas geralmente são definidas como uma forma especializada de propriedade de dependência que não possui o "invólucro" de propriedade convencional.

Este tópico contém as seguintes seções.

  • Pré-requisitos
  • Por que usar propriedades anexadas
  • Propriedades anexadas em XAML
  • Como propriedades anexadas são usadas pelo tipo proprietário
  • Propriedades anexadas no código
  • Metadados de propriedade anexada
  • Propriedades anexadas personalizadas
  • Aprendendo mais sobre propriedades anexadas
  • Tópicos relacionados

Pré-requisitos

Este tópico assume que você entende propriedades de dependência de uma perspectiva de um consumidor de propriedades de dependência existentes em classes Windows Presentation Foundation (WPF), e já leu Visão geral sobre propriedades de dependência. Para que você siga os exemplos deste tópico, você também deve entender Extensible Application Markup Language (XAML) e saber como escrever aplicações WPF.

Por que usar propriedades anexadas

Uma das finalidades de uma propriedade anexada é permitir que diferentes elementos-filhos especifiquem valores únicos para uma propriedade que na verdade é definida em um elemento-pai. Uma aplicação específica desta situação é fazer com que elementos-filhos informem o elemento-pai sobre como elas devem ser apresentados na interface do usuário (UI). Um exemplo é a propriedade DockPanel.Dock. A propriedade DockPanel.Dock é criada como uma propriedade anexada porque ela foi projetada para ser definida em elementos que estão contidos em um DockPanel, em vez de no próprio DockPanel. A classe DockPanel define o campo estático DependencyProperty chamado DockProperty e, em seguida, fornece os métodos GetDock e SetDock como acessadores públicos para a propriedade anexada.

Propriedades anexadas em XAML

Em XAML, você define propriedades anexadas utilizando a sintaxe AttachedPropertyProvider. PropertyName 

Veja a seguir um exemplo de como você pode definir DockPanel.Dock em XAML:

<DockPanel>
  <CheckBox DockPanel.Dock="Top">Hello</CheckBox>
</DockPanel>

Observe que o uso é semelhante a uma propriedade estática; você sempre referência o tipo DockPanel que registra e é proprietário da propriedade anexada, em vez de referir-se a qualquer instância especificada pelo nome.

Além disso, como uma propriedade anexada em XAML é um atributo que você definiu em marcação, a única operação relevante é a de atribução. Não é possível obter diretamente uma propriedade em XAML, embora existam alguns mecanismos indiretos para comparar valores, tais como disparadores em estilos (para saber mais, consulte Styling and Templating).

Implementação de propriedades anexadas na WPF

Em Windows Presentation Foundation (WPF), a maioria das propriedades anexadas que existem nos tipos do WPF é implementada como propriedades de dependência. Propriedades anexadas são um conceito ligado a XAML, enquanto que as propriedades de dependência são um conceito ligado a WPF. Como propriedades anexadas em WPF são propriedades de dependência, elas suportam conceitos ligados a propriedade de dependência, tais como metadados de propriedades e valores padrão a partir desses metadados de propriedade.

Como propriedades anexadas são usadas pelo tipo proprietário

Embora propriedades anexadas sejam configuráveis em qualquer objeto, isto não significa que a definição da propriedade produzirá um resultado tangível, ou que o valor será usado por outro objeto. Em geral, propriedades anexadas servem para que objetos provenientes de uma grande variedade de hierarquias de classes ou relacionamentos lógicos possam relatar informações comuns ao tipo proprietário. O tipo que define a propriedade anexada geralmente segue um desses modelos:

  • O tipo que define a propriedade anexada é projetado de tal forma que ele possa ser o elemento-pai dos elementos que irão definir valores para a propriedade anexada. O tipo itera seus elementos-filhos por lógica interna, obtém os valores, e age de acordo com os valores de alguma maneira.

  • O tipo que define a propriedade anexada será usado como o elemento-filho para uma variedade de elementos-pai possíveis e modelos de conteúdo.

  • O tipo que define a propriedade anexada representa um serviço. Outros tipos definem valores para a propriedade anexada. Em seguida, quando o elemento que definiu a propriedade é avaliado no contexto do serviço, os valores das propriedade anexadas são obtidos por meio da lógica interna da classe de serviço.

Um exemplo de uma propriedade anexada definida pelo pai

A situação mais comum em que WPF define uma propriedade anexada é quando um elemento-pai suporta uma coleção elementos-filho e também implementa um comportamento no qual as especificidades do comportamento são relatadas individualmente para cada elemento-filho.

DockPanel define a propriedade anexada DockPanel.Dock, e DockPanel possui código em nível de classe como parte de sua lógica de renderização (especificamente, MeasureOverride e ArrangeOverride). Uma instância de DockPanel sempre verificará se qualquer um dos seus elementos-filho imediatos tiver definido um valor para DockPanel.Dock. Se sim, esses valores se tornam dados de entrada para a lógica de renderização aplicada àquele elemento-filho específico. Instâncias de DockPanel aninhadas tratam suas próprias coleções de elementos-filho imediatos, mas esse comportamento é específico da implementação. Teoricamente, é possível que propriedades anexadas influenciem elementos além do pai imediato. Se a propriedade anexada DockPanel.Dock for definida em um elemento que tenha não elemento-pai DockPanel para agir sobre ela, nenhum erro ou exceção será gerada. Isso simplesmente significa que um valor da propriedade global foi definida, mas ele não tem nenhum pai DockPanel atual que possa consumir as informações.

Propriedades anexadas no código

Propriedades anexadas em WPF não têm os métodos CLR de "invólucro" comuns para acesso fácil de get/set. Isso ocorre porque a propriedade anexada não necessariamente é parte do namespace CLR para instâncias em que a propriedade está definida. No entanto, um leitor XAML deve ser capaz de definir esses valores quando o XAML for processado. Para ser uma propriedade anexa eficaz, o tipo proprietário da propriedade anexada deve implementar métodos acessadores dedicados na forma GetNomeDaPropriedade e SetNomeDaPropriedade. Esses métodos acessadores dedicados são também como você deve obter ou definir a propriedade anexada no código. A partir de uma perspectiva de código, uma propriedade anexada é semelhante a um campo que tem métodos acessadores em vez dos acessadores da propriedade, e esse campo pode existir em qualquer objeto sem precisar ser especificamente definido.

O exemplo a seguir mostra como você pode definir uma propriedade anexada no código. Nesse exemplo, myCheckBox é uma instância da classe CheckBox.

DockPanel myDockPanel = new DockPanel();
CheckBox myCheckBox = new CheckBox();
myCheckBox.Content = "Hello";
myDockPanel.Children.Add(myCheckBox);
DockPanel.SetDock(myCheckBox, Dock.Top);

Semelhante ao caso XAML, se myCheckBox ainda não tivesse sido adicionado como um elemento-filho de myDockPanel ao chegar na terceira linha do código, a quarta linha de código não geraria uma exceção, mas o valor da propriedade não interagiria com um DockPanel pai e, portanto, faria nada. Apenas um valor DockPanel.Dock definido em um elemento-filho combinado com a presença de um elemento-pai DockPanel fará com que haja um comportamento eficaz no aplicativo renderizado.

Metadados de propriedade anexada

Ao registrar a propriedade, FrameworkPropertyMetadata é definido para especificar características da propriedade, tais como se a propriedade afeta a renderização, medidas, e assim por diante. Os metadados de uma propriedade anexada são geralmente idênticos àqueles definidos em uma propriedade de dependência. Se você especificar um valor padrão em uma substituição para metadados de propriedade anexada, esse valor será o valor padrão da propriedade anexada implícita em instâncias da classe que faz a substituição. Especificamente, o valor padrão será relatado se algum processo consultar o valor de uma propriedade anexada por meio do método acessador Get para essa propriedade, especificando uma instância da classe em que você especificou os metadados, e o valor para essa propriedade anexada não tenha sido definido.

Se você desejar habilitar herança de valor em uma propriedade, você deve usar propriedades anexadas em vez de propriedades de dependência não anexadas. Para obter detalhes, consulte:Herança de Valor de Propriedade.

Propriedades anexadas personalizadas

Quando criar uma propriedade anexada

Você pode criar uma propriedade anexada quando houver um motivo para ter um mecanismo de configuração de propriedade disponível para as classes além da classe que fez a definição. A situação mais comuns para isso é o layout. Exemplos de propriedades de layout existentes são DockPanel.Dock, Panel.ZIndex e Canvas.Top. A situação permitida aqui é que os elementos que existem como elementos-filho para elementos que controlam o layout conseguem exprimir requisitos de layout para seus elementos-pai no layout, cada um configurando um valor da propriedade que o pai definiu como uma propriedade anexada.

Outra situação para usar uma propriedade anexada é quando sua classe representa um serviço, e você deseja que classes possam integrar o serviço de forma mais transparente.

Ainda outra situação é receber suporte a WPF Designer Visual Studio 2008, tal como edição de janelas Properties. Para obter mais informações, consulte Visão geral sobre criação de controles.

Como mencionado anteriormente, você deve registrar como uma propriedade anexada se você quiser usar herança de valored de propriedade.

Como criar uma propriedade anexada

Se sua classe estiver definindo a propriedade anexada estritamente para uso em outros tipos, então a classe não precisa derivar de DependencyObject. Mas você precisa derivar de DependencyObject se você seguir o modelo geral de WPF, onde sua propriedade anexada também é uma propriedade de dependência.

Defina sua propriedade anexada como um propriedade de dependência, declarando um campo public static readonly do tipo DependencyProperty. Você define este campo usando o valor de retorno do método RegisterAttached. O nome do campo deve corresponder ao nome da propriedade anexada, concatenado com a string Property, para seguir o padrão estabelecido pelo WPF de nomeação dos campos de identificação versus as propriedades que eles representam. O provedor de propriedades anexadas também deve fornecer métodos estáticos GetNomeDaPropriedade e SetNomeDaPropriedade como acessadores para a propriedade anexada; a falta desses métodos acarretará na impossibilidade do sistema de usar sua propriedade anexada.

O acessador Get

A assinatura do acessador GetNomeDaPropriedade deve ser:

public static object GetNomeDaPropriedade(object target)

  • O objeto target pode ser especificado como um tipo mais específico na sua implementação. Por exemplo, o método DockPanel.GetDock declara o parâmetro com o tipo UIElement, porque a propriedade anexada destina-se somente à definição em instâncias de UIElement.

  • O valor de retorno pode ser especificado como um tipo mais específico na sua implementação. Por exemplo, o método GetDock declara-o como Dock, porque o valor só pode ser definido como aquela enumeração.

O acessador Set

A assinatura do acessador SetNomeDaPropriedade deve ser:

public static void SetNomeDaPropriedade(object target, object value)

  • O objeto target pode ser especificado como um tipo mais específico na sua implementação. Por exemplo, o método SetDock declara o parâmetro com o tipo UIElement, porque a propriedade anexada destina-se somente à definição em instâncias de UIElement.

  • O objeto value pode ser especificado como um tipo mais específico na sua implementação. Por exemplo, o método SetDock declara-o como Dock, porque o valor só pode ser definido como aquela enumeração. Lembre-se de que o valor para este método é a entrada proveniente de carregador de XAML quando ele encontra sua propriedade anexada em uma marcação de uso de propriedades anexadas. Essa entrada é o valor especificado como um valor de atributo XAML na marcação. Portanto, deve haver suporte a extensão de marcação, serializador de valores, ou conversão de tipos para o tipo que você estiver usando, de modo que o tipo apropriado possa ser criado a partir do valor de atributo (que é basicamente apenas uma sequência de caracteres).

O exemplo a seguir mostra o registro de propriedade de dependência (usando o método RegisterAttached), bem como os acessadores GetNomeDaPropriedade e SetNomeDaPropriedade. No exemplo, o nome da propriedade anexada é IsBubbleSource. Portanto, os acessadores devem ser denominados GetIsBubbleSource e SetIsBubbleSource.

public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
  "IsBubbleSource",
  typeof(Boolean),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
);
public static void SetIsBubbleSource(UIElement element, Boolean value)
{
  element.SetValue(IsBubbleSourceProperty, value);
}
public static Boolean GetIsBubbleSource(UIElement element)
{
  return (Boolean)element.GetValue(IsBubbleSourceProperty);
}

Atributos da propriedade anexada

WPF define vários Atributos do .NET Framework destinados ao fornecimento de informações sobre propriedades anexadas aos processos de reflexão e aos usuários típicos de reflexão e informações de propriedade (tais como designers). Como propriedades anexadas tem um tipo de escopo ilimitado, os designers precisam encontrar uma maneira para evitar sobrecarregar os usuários com uma lista global de todas as propriedades anexadas que são definidas em uma implementação de tecnologia específica que usa XAML. O Atributos do .NET Framework que o WPF define para propriedades anexadas pode ser usado para atribuir um escopo às situações onde uma determinada propriedade anexada deve ser mostrada em uma janela de propriedades. Talvez você deva considerar aplicar esses atributos a suas próprias propriedades anexadas personalizadas. A finalidade e a sintaxe de Atributos do .NET Framework é descrita nas páginas de referência adequadas:

Aprendendo mais sobre propriedades anexadas

  • Para obter mais informações sobre como criar uma propriedade anexada, consulte Como: Register an Attached Property.

  • Para situações de uso mais avançadas para as propriedades de dependência e propriedades anexadas, consulte Propriedades de Dependência Personalizada.

  • Você pode também registrar uma propriedade como uma propriedade anexada e como um propriedade de dependência, mas ainda assim expor implementações de "invólucro". Nesse caso, a propriedade pode ser definida tanto nesse elemento como em qualquer elemento através da sintaxe XAML para propriedades anexadas. Um exemplo de uma propriedade com uma situação adequada tanto para o uso padrão quanto para o uso anexado é FrameworkElement.FlowDirection.

Consulte também

Tarefas

Como: Register an Attached Property

Conceitos

Visão geral sobre propriedades de dependência

Propriedades de Dependência Personalizada

XAML Overview

Referência

DependencyProperty