Riepilogo del capitolo 11. Infrastruttura associabile
Nota
Questo libro è stato pubblicato nella primavera del 2016, e non è stato aggiornato da allora. C'è molto nel libro che rimane prezioso, ma alcuni materiali sono obsoleti, e alcuni argomenti non sono più completamente corretti o completi.
Ogni programmatore C# ha familiarità con le proprietà C#. Le proprietà contengono una funzione di accesso set e/o una funzione di accesso get . Vengono spesso chiamate proprietà CLR per Common Language Runtime.
Xamarin.Forms definisce una definizione di proprietà avanzata denominata proprietà associabile incapsulata dalla BindableProperty
classe e supportata dalla BindableObject
classe . Queste classi sono correlate ma piuttosto distinte: BindableProperty
viene usato per definire la proprietà stessa. BindableObject
È come object
in questo caso una classe di base per le classi che definiscono proprietà associabili.
Gerarchia di Xamarin.Forms classi
L'esempio ClassHierarchy usa la reflection per visualizzare una gerarchia di classi di Xamarin.Forms e dimostrare il ruolo cruciale svolto da BindableObject
in questa gerarchia. BindableObject
deriva da Object
e è la classe padre da Element
cui VisualElement
deriva. Si tratta della classe padre a Page
e View
, che è la classe padre in Layout
:
Un'occhiata a BindableObject e BindableProperty
Nelle classi che derivano da BindableObject
molte proprietà CLR si dice che siano "supportate da" proprietà associabili. Ad esempio, la Text
proprietà della Label
classe è una proprietà CLR, ma la Label
classe definisce anche un campo di sola lettura statico pubblico denominato TextProperty
di tipo BindableProperty
.
Un'applicazione può impostare o ottenere la Text
proprietà di Label
normalmente oppure l'applicazione può impostare Text
chiamando il SetValue
metodo definito da BindableObject
con un Label.TextProperty
argomento . Analogamente, un'applicazione può ottenere il valore della Text
proprietà chiamando di nuovo il GetValue
metodo con un Label.TextProperty
argomento . Questo è dimostrato dall'esempio PropertySettings .
In effetti, la Text
proprietà CLR viene interamente implementata usando i SetValue
metodi e GetValue
definiti in BindableObject
combinazione con la Label.TextProperty
proprietà statica.
BindableObject
e BindableProperty
fornire supporto per:
- Assegnare valori predefiniti alle proprietà
- Archiviazione dei valori correnti
- Fornire meccanismi per la convalida dei valori delle proprietà
- Mantenimento della coerenza tra le proprietà correlate in una singola classe
- Risposta alle modifiche alle proprietà
- Attivazione delle notifiche quando una proprietà sta per cambiare o è stata modificata
- Supporto del data binding
- Stili di supporto
- Supporto di risorse dinamiche
Ogni volta che una proprietà supportata da una proprietà associabile cambia, BindableObject
genera un PropertyChanged
evento che identifica la proprietà modificata. Questo evento non viene generato quando la proprietà è impostata sullo stesso valore.
Alcune proprietà non sono supportate da proprietà associabili e alcune Xamarin.Forms classi, ad esempio Span
, non derivano da BindableObject
. Solo una classe che deriva da BindableObject
può supportare proprietà associabili perché BindableObject
definisce i SetValue
metodi e GetValue
.
Poiché Span
non deriva da BindableObject
, nessuna delle relative proprietà, ad esempio Text
, è supportata da una proprietà associabile. Ecco perché un'impostazione DynamicResource
sulla Text
proprietà di Span
genera un'eccezione nell'esempio DynamicVsStatic nel capitolo precedente. L'esempio DynamicVsStaticCode illustra come impostare risorse dinamiche nel codice usando il SetDynamicResource
metodo definito da Element
. Il primo argomento è un oggetto di tipo BindableProperty
.
Analogamente, il SetBinding
metodo definito da BindableObject
ha un primo argomento di tipo BindableProperty
.
Definizione di proprietà associabili
È possibile definire proprietà associabili personalizzate usando il metodo statico per creare un campo statico BindableProperty.Create
di sola lettura di tipo BindableProperty
.
Questa operazione è illustrata nella AltLabel
classe nella Xamarin.Formslibreria Book.Toolkit. La classe deriva da Label
e consente di specificare una dimensione del carattere espressa in punti. Viene illustrato nell'esempio PointSizedText .
Sono necessari quattro argomenti del BindableProperty.Create
metodo:
propertyName
: nome di testo della proprietà (uguale al nome della proprietà CLR)returnType
: tipo della proprietà CLRdeclaringType
: tipo della classe che dichiara la proprietàdefaultValue
: valore predefinito della proprietà
Poiché defaultValue
è di tipo object
, il compilatore deve essere in grado di determinare il tipo del valore predefinito. Ad esempio, se returnType
è double
, deve defaultValue
essere impostato su un valore simile a 0.0 anziché solo 0 oppure la mancata corrispondenza del tipo attiverà un'eccezione in fase di esecuzione.
È anche molto comune che una proprietà associabile includa:
propertyChanged
: metodo statico chiamato quando la proprietà cambia valore. Il primo argomento è l'istanza della classe la cui proprietà è stata modificata.
Gli altri argomenti da BindableProperty.Create
non sono comuni:
defaultBindingMode
: usato in relazione all'associazione dati (come illustrato nel capitolo 16. Data binding)validateValue
: callback per verificare la presenza di un valore validopropertyChanging
: callback per indicare quando la proprietà sta per cambiarecoerceValue
: callback per forzare un valore impostato su un altro valoredefaultValueCreate
: callback per creare un valore predefinito che non può essere condiviso tra le istanze della classe (ad esempio, una raccolta)
Proprietà associabile di sola lettura
Una proprietà associabile può essere di sola lettura. La creazione di una proprietà associabile di sola lettura richiede la chiamata al metodo BindableProperty.CreateReadOnly
statico per definire un campo statico di sola lettura privato di tipo BindablePropertyKey
.
Definire quindi l'accesore della proprietà set
CLR per private
chiamare un SetValue
overload con l'oggetto BindablePropertyKey
. Ciò impedisce che la proprietà venga impostata all'esterno della classe .
Questa operazione è illustrata nella CountedLabel
classe usata nell'esempio BaskervillesCount .