Visão geral das propriedades anexadas
Uma propriedade anexada é um conceito XAML. As propriedades anexadas permitem que pares de propriedade/valor adicionais sejam definidos em um objeto, mas as propriedades não fazem parte da definição do objeto original. As propriedades anexadas normalmente são definidas como uma forma especializada de propriedade de dependência que não tem um wrapper de propriedade convencional no modelo de objeto do tipo proprietário.
Pré-requisitos
Presumimos que você entenda o conceito básico de propriedades de dependência e tenha lido Visão geral das propriedades de dependência.
Propriedades anexadas em XAML
Em XAML, você define propriedades anexadas usando a sintaxe AttachedPropertyProvider.PropertyName. Aqui está um exemplo de como você pode definir Canvas.Left em XAML.
<Canvas>
<Button Canvas.Left="50">Hello</Button>
</Canvas>
Observação
Estamos apenas usando Canvas.Left como um exemplo de propriedade anexada sem explicar completamente por que você a usaria. Se você quiser saber mais sobre para que serve Canvas.Left e como o Canvas lida com seus filhos de layout, consulte o tópico de referência do Canvas ou Definir layouts com XAML.
Por que usar propriedades anexadas?
As propriedades anexadas são uma maneira de escapar das convenções de codificação que podem impedir que objetos diferentes em uma relação comuniquem informações entre si em tempo de execução. Certamente é possível colocar propriedades em uma classe base comum para que cada objeto possa obter e definir essa propriedade. Mas, eventualmente, o grande número de cenários em que você pode querer fazer isso inchará suas classes base com propriedades compartilháveis. Pode até introduzir casos em que pode haver apenas duas centenas de descendentes tentando usar uma propriedade. Isso não é um bom design de classe. Para resolver isso, o conceito de propriedade anexada permite que um objeto atribua um valor a uma propriedade que sua própria estrutura de classe não define. A classe de definição pode ler o valor de objetos filho em tempo de execução depois que os vários objetos são criados em uma árvore de objetos.
Por exemplo, elementos filho podem usar propriedades anexadas para informar seu elemento pai de como eles devem ser apresentados na interface do usuário. Esse é o caso da propriedade anexada Canvas.Left . Canvas.Left é criado como uma propriedade anexada porque é definido em elementos contidos em um elemento Canvas, em vez de no próprio Canvas. Qualquer elemento filho possível usa Canvas.Left e Canvas.Top para especificar seu deslocamento de layout dentro do pai do contêiner de layout Canvas . As propriedades anexadas possibilitam que isso funcione sem sobrecarregar o modelo de objeto do elemento base com muitas propriedades que se aplicam a apenas um dos muitos contêineres de layout possíveis. Em vez disso, muitos dos contêineres de layout implementam seu próprio conjunto de propriedades anexadas.
Para implementar a propriedade anexada, a classe Canvas define um campo estático DependencyProperty chamado Canvas.LeftProperty. Em seguida, o Canvas fornece os métodos SetLeft e GetLeft como acessadores públicos para a propriedade anexada, para habilitar a configuração XAML e o acesso ao valor em tempo de execução. Para XAML e para o sistema de propriedades de dependência, esse conjunto de APIs atende a um padrão que habilita uma sintaxe XAML específica para propriedades anexadas e armazena o valor no repositório de propriedades de dependência.
Como o tipo proprietário usa propriedades anexadas
Embora as propriedades anexadas possam ser definidas em qualquer elemento XAML (ou em qualquer DependencyObject subjacente), isso não significa automaticamente que a configuração da propriedade produza um resultado tangível ou que o valor seja acessado. O tipo que define a propriedade anexada normalmente segue um destes cenários:
- O tipo que define a propriedade anexada é o pai em uma relação de outros objetos. Os objetos filho definirão valores para a propriedade anexada. O tipo de proprietário da propriedade anexada tem algum comportamento inato que itera por meio de seus elementos filho, obtém os valores e age sobre esses valores em algum ponto do tempo de vida do objeto (uma ação de layout, SizeChanged etc.)
- O tipo que define a propriedade anexada é usado como o elemento filho para uma variedade de possíveis elementos pai e modelos de conteúdo, mas as informações não são necessariamente informações de layout.
- A propriedade anexada relata informações para um serviço, não para outro elemento da interface do usuário.
Para obter mais informações sobre esses cenários e tipos proprietários, consulte a seção "Mais sobre Canvas.Left" de Propriedades anexadas personalizadas.
Propriedades anexadas no código
As propriedades anexadas não têm os wrappers de propriedade típicos para facilitar o acesso de obtenção e configuração como outras propriedades de dependência. Isso ocorre porque a propriedade anexada não é necessariamente parte do modelo de objeto centrado no código para instâncias em que a propriedade é definida. (É permitido, embora incomum, definir uma propriedade que seja uma propriedade anexada que outros tipos podem definir em si mesmos e que também tenha um uso de propriedade convencional no tipo proprietário.)
Há duas maneiras de definir uma propriedade anexada no código: usar as APIs do sistema de propriedades ou usar os acessadores de padrão XAML. Essas técnicas são praticamente equivalentes em termos de resultado final, portanto, qual usar é principalmente uma questão de estilo de codificação.
Usando o sistema de propriedades
As propriedades anexadas para o Tempo de Execução do Windows são implementadas como propriedades de dependência, para que os valores possam ser armazenados no repositório de propriedades de dependência compartilhada pelo sistema de propriedades. Portanto, as propriedades anexadas expõem um identificador de propriedade de dependência na classe proprietária.
Para definir uma propriedade anexada no código, chame o método SetValue e passe o campo DependencyProperty que serve como o identificador para essa propriedade anexada. (Você também passa o valor a ser definido.)
Para obter o valor de uma propriedade anexada no código, chame o método GetValue, passando novamente o campo DependencyProperty que serve como identificador.
Usando o padrão de acessador XAML
Um processador XAML deve ser capaz de definir valores de propriedade anexados quando o XAML é analisado em uma árvore de objetos. O tipo de proprietário da propriedade anexada deve implementar métodos de acessador dedicados nomeados no formulário GetPropertyName e SetPropertyName. Esses métodos de acessador dedicados também são uma maneira de obter ou definir a propriedade anexada no código. De uma perspectiva de código, uma propriedade anexada é semelhante a um campo de suporte que tem acessadores de método em vez de acessadores de propriedade, e esse campo de suporte pode existir em qualquer objeto em vez de ter que ser definido especificamente.
O exemplo a seguir mostra como você pode definir uma propriedade anexada no código por meio da API do acessador XAML. Neste exemplo, myCheckBox
é uma instância da classe CheckBox. A última linha é o código que realmente define o valor; As linhas anteriores apenas estabelecem as instâncias e sua relação pai-filho. A última linha não comentada é a sintaxe se você usar o sistema de propriedades. A última linha comentada é a sintaxe se você usar o padrão de acessador XAML.
Canvas myC = new Canvas();
CheckBox myCheckBox = new CheckBox();
myCheckBox.Content = "Hello";
myC.Children.Add(myCheckBox);
myCheckBox.SetValue(Canvas.TopProperty,75);
//Canvas.SetTop(myCheckBox, 75);
Dim myC As Canvas = New Canvas()
Dim myCheckBox As CheckBox= New CheckBox()
myCheckBox.Content = "Hello"
myC.Children.Add(myCheckBox)
myCheckBox.SetValue(Canvas.TopProperty,75)
' Canvas.SetTop(myCheckBox, 75)
Canvas myC;
CheckBox myCheckBox;
myCheckBox.Content(winrt::box_value(L"Hello"));
myC.Children().Append(myCheckBox);
myCheckBox.SetValue(Canvas::TopProperty(), winrt::box_value(75));
// Canvas::SetTop(myCheckBox, 75);
Canvas^ myC = ref new Canvas();
CheckBox^ myCheckBox = ref new CheckBox();
myCheckBox->Content="Hello";
myC->Children->Append(myCheckBox);
myCheckBox->SetValue(Canvas::TopProperty,75);
// Canvas::SetTop(myCheckBox, 75);
Propriedades anexadas personalizadas
Para obter exemplos de código de como definir propriedades anexadas personalizadas e mais informações sobre os cenários para usar uma propriedade anexada, consulte Propriedades anexadas personalizadas.
Sintaxe especial para referências de propriedade anexada
O ponto em um nome de propriedade anexado é uma parte fundamental do padrão de identificação. Às vezes, há ambiguidades quando uma sintaxe ou situação trata o ponto como tendo algum outro significado. Por exemplo, um ponto é tratado como uma passagem de modelo de objeto para um caminho de associação. Na maioria dos casos que envolvem essa ambiguidade, há uma sintaxe especial para uma propriedade anexada que permite que o ponto interno ainda seja analisado como o proprietário.separador de propriedade de uma propriedade anexada.
- Para especificar uma propriedade anexada como parte de um caminho de destino para uma animação, coloque o nome da propriedade anexada entre parênteses ("()")—por exemplo, "(Canvas.Left)". Para obter mais informações, consulte Sintaxe do Property-path.
Aviso
Uma limitação existente da implementação XAML do Tempo de Execução do Windows é que você não pode animar uma propriedade anexada personalizada.
- Para especificar uma propriedade anexada como a propriedade de destino para uma referência de recurso de um arquivo de recurso para x:Uid, use uma sintaxe especial que injeta um estilo de código, totalmente qualificado usando: declaração entre colchetes ("[]"), para criar uma quebra de escopo deliberada. Por exemplo, supondo que exista um elemento
<TextBlock x:Uid="Title" />
, a chave de recurso no arquivo de recurso que tem como destino o valor Canvas.Top nessa instância é "Title". usando:Windows.UI.Xaml.Controls]Canvas.Top". Para obter mais informações sobre arquivos de recurso e XAML, consulte Guia de início rápido: traduzindo recursos da interface do usuário.