Resumo do Capítulo 11. A infraestrutura vinculável
Observação
Este livro foi publicado na primavera de 2016, e não foi atualizado desde então. Há muito no livro que permanece valioso, mas parte do material está desatualizado, e alguns tópicos não estão mais totalmente corretos ou completos.
Todo programador C# está familiarizado com as propriedades do C#. As propriedades contêm um acessador definido e/ou um acessador get . Eles geralmente são chamados de propriedades CLR para o Common Language Runtime.
Xamarin.Forms Define uma definição de propriedade avançada chamada uma propriedade vinculável encapsulada BindableProperty
pela classe e suportada BindableObject
pela classe. Essas classes são relacionadas, mas bastante distintas: O BindableProperty
é usado para definir a propriedade em si, BindableObject
é como object
se fosse uma classe base para classes que definem propriedades vinculáveis.
A Xamarin.Forms hierarquia de classes
O exemplo ClassHierarchy usa a reflexão para exibir uma hierarquia de classes e demonstrar o papel crucial desempenhado Xamarin.Forms por BindableObject
essa hierarquia. BindableObject
deriva de Object
e é a classe pai da Element
qual VisualElement
deriva. Esta é a classe pai para Page
e View
, que é a classe pai para Layout
:
Uma espiada em BindableObject e BindableProperty
Nas classes que derivam de BindableObject
muitas propriedades CLR são ditas como "apoiadas por" propriedades vinculáveis. Por exemplo, a Text
Label
propriedade da classe é uma propriedade CLR, mas a Label
classe também define um campo somente leitura estático público chamado TextProperty
do tipo BindableProperty
.
Um aplicativo pode definir ou obter a Text
propriedade de Label
normalmente, ou o aplicativo pode definir o Text
chamando o SetValue
método definido por BindableObject
com um Label.TextProperty
argumento. Da mesma forma, um aplicativo pode obter o valor da Text
propriedade chamando o GetValue
método, novamente com um Label.TextProperty
argumento. Isso é demonstrado pelo exemplo PropertySettings .
De fato, a Text
propriedade CLR é inteiramente implementada usando os SetValue
métodos e GetValue
definidos por BindableObject
em conjunto com a Label.TextProperty
propriedade estática.
BindableObject
e BindableProperty
fornecer suporte para:
- Fornecendo valores padrão às propriedades
- Armazenando seus valores atuais
- Fornecendo mecanismos para validar valores de propriedade
- Mantendo a consistência entre propriedades relacionadas em uma única classe
- Respondendo a alterações de propriedade
- Disparando notificações quando uma propriedade está prestes a ser alterada ou foi alterada
- Suporte à vinculação de dados
- Estilos de suporte
- Suporte a recursos dinâmicos
Sempre que uma propriedade que é apoiada por uma propriedade vinculável é alterada, BindableObject
dispara um PropertyChanged
evento identificando a propriedade que foi alterada. Esse evento não é acionado quando a propriedade é definida com o mesmo valor.
Algumas propriedades não são apoiadas por propriedades vinculáveis, e algumas Xamarin.Forms classes — como Span
— não derivam de BindableObject
. Somente uma classe derivada de BindableObject
pode oferecer suporte a propriedades vinculáveis porque BindableObject
define os SetValue
métodos e GetValue
.
Porque Span
não deriva de BindableObject
, nenhuma de suas propriedades — como Text
— é lastreada por uma propriedade vinculável. É por isso que uma DynamicResource
configuração na Text
propriedade de Span
gera uma exceção no exemplo DynamicVsStatic no capítulo anterior. O exemplo DynamicVsStaticCode demonstra como definir recursos dinâmicos no código usando o SetDynamicResource
método definido por Element
. O primeiro argumento é um objeto do tipo BindableProperty
.
Da mesma forma, o SetBinding
método definido por BindableObject
tem um primeiro argumento do tipo BindableProperty
.
Definindo propriedades vinculáveis
Você pode definir suas próprias propriedades vinculáveis usando o método estático BindableProperty.Create
para criar um campo estático somente leitura do tipo BindableProperty
.
Isso é demonstrado na AltLabel
classe na Xamarin.Formsbiblioteca Book.Toolkit. A classe deriva de Label
e permite especificar um tamanho de fonte em pontos. Isso é demonstrado no exemplo PointSizedText.
Quatro argumentos do BindableProperty.Create
método são necessários:
propertyName
: o nome de texto da propriedade (o mesmo que o nome da propriedade CLR)returnType
: o tipo da propriedade CLRdeclaringType
: o tipo da classe que declara a propriedadedefaultValue
: o valor padrão da propriedade
Como defaultValue
é do tipo object
, o compilador deve ser capaz de determinar o tipo do valor padrão. Por exemplo, se o returnType
é double
, o defaultValue
deve ser definido como algo como 0.0 em vez de apenas 0, ou a incompatibilidade de tipo acionará uma exceção em tempo de execução.
Também é muito comum que uma propriedade vinculável inclua:
propertyChanged
: um método estático chamado quando a propriedade altera o valor. O primeiro argumento é a instância da classe cuja propriedade foi alterada.
Os outros argumentos não BindableProperty.Create
são tão comuns:
defaultBindingMode
: utilizado em ligação com a ligação de dados (conforme discutido no capítulo 16. Vinculação de dados)validateValue
: um retorno de chamada para verificar um valor válidopropertyChanging
: um retorno de chamada para indicar quando a propriedade está prestes a mudarcoerceValue
: um retorno de chamada para coagir um valor definido para outro valordefaultValueCreate
: um retorno de chamada para criar um valor padrão que não pode ser compartilhado entre instâncias da classe (por exemplo, uma coleção)
A propriedade vinculável somente leitura
Uma propriedade vinculável pode ser somente leitura. A criação de uma propriedade vinculável somente leitura requer chamar o método BindableProperty.CreateReadOnly
estático para definir um campo estático somente leitura privado do tipo BindablePropertyKey
.
Em seguida, defina o acessador da propriedade set
CLR como private
para chamar uma SetValue
sobrecarga com o BindablePropertyKey
objeto. Isso impede que a propriedade seja definida fora da classe.
Isso é demonstrado na CountedLabel
classe usada na amostra BaskervillesCount .