Xamarin.Forms Proprietà associabili
Le proprietà associabili estendono la funzionalità delle proprietà CLR tramite il supporto di una proprietà con un BindableProperty
tipo, invece di eseguire il backup di una proprietà con un campo. Lo scopo delle proprietà associabili è fornire un sistema di proprietà che supporta data binding, stili, modelli e valori impostati tramite relazioni padre-figlio. Inoltre, le proprietà associabili possono fornire valori predefiniti, convalida dei valori delle proprietà e callback che monitorano le modifiche delle proprietà.
Le proprietà devono essere implementate come proprietà associabili per supportare una o più delle funzionalità seguenti:
- Funge da proprietà di destinazione valida per il data binding.
- Impostazione della proprietà tramite uno stile.
- Specificare un valore di proprietà predefinito diverso da quello predefinito per il tipo della proprietà.
- Convalida del valore della proprietà.
- Monitoraggio delle modifiche delle proprietà.
Esempi di Xamarin.Forms proprietà associabili includono Label.Text
, Button.BorderRadius
e StackLayout.Orientation
. Ogni proprietà associabile ha un campo di tipo BindableProperty
corrispondente public static readonly
esposto nella stessa classe e che è l'identificatore della proprietà associabile. Ad esempio, l'identificatore di proprietà associabile corrispondente per la Label.Text
proprietà è Label.TextProperty
.
Creare una proprietà associabile
Il processo di creazione di una proprietà associabile è il seguente:
- Creare un'istanza
BindableProperty
con uno degli overload delBindableProperty.Create
metodo. - Definire le funzioni di accesso alle proprietà per l'istanza
BindableProperty
di .
Tutte le BindableProperty
istanze devono essere create nel thread dell'interfaccia utente. Ciò significa che solo il codice eseguito nel thread dell'interfaccia utente può ottenere o impostare il valore di una proprietà associabile. Tuttavia, BindableProperty
è possibile accedere alle istanze da altri thread eseguendo il marshalling al thread dell'interfaccia utente con il Device.BeginInvokeOnMainThread
metodo .
Creare una proprietà
Per creare un'istanza BindableProperty
di , la classe contenitore deve derivare dalla BindableObject
classe . Tuttavia, la BindableObject
classe è elevata nella gerarchia di classi, quindi la maggior parte delle classi usate per la funzionalità dell'interfaccia utente supporta le proprietà associabili.
È possibile creare una proprietà associabile dichiarando una public static readonly
proprietà di tipo BindableProperty
. La proprietà associabile deve essere impostata sul valore restituito di uno degli overload del BindableProperty.Create
metodo. La dichiarazione deve trovarsi all'interno del corpo della BindableObject
classe derivata, ma all'esterno di qualsiasi definizione di membro.
È necessario specificare almeno un identificatore durante la creazione di un BindableProperty
oggetto , insieme ai parametri seguenti:
- Nome dell'oggetto
BindableProperty
. - Tipo della proprietà.
- Tipo dell'oggetto proprietario.
- Il valore predefinito per la proprietà. In questo modo, la proprietà restituisce sempre un valore predefinito specifico quando non è impostata e può essere diversa dal valore predefinito per il tipo della proprietà. Il valore predefinito verrà ripristinato quando il
ClearValue
metodo viene chiamato sulla proprietà associabile.
Importante
La convenzione di denominazione per le proprietà associabili è che l'identificatore della proprietà associabile deve corrispondere al nome della proprietà specificato nel Create
metodo, con "Property" aggiunto.
Il codice seguente mostra un esempio di proprietà associabile, con un identificatore e valori per i quattro parametri obbligatori:
public static readonly BindableProperty EventNameProperty =
BindableProperty.Create ("EventName", typeof(string), typeof(EventToCommandBehavior), null);
Verrà creata un'istanza BindableProperty
denominata EventNameProperty
, di tipo string
. La proprietà è di proprietà della EventToCommandBehavior
classe e ha un valore predefinito .null
Facoltativamente, quando si crea un'istanza BindableProperty
, è possibile specificare i parametri seguenti:
- Modalità di associazione. Viene usato per specificare la direzione in cui le modifiche apportate al valore della proprietà verranno propagate. Nella modalità di associazione predefinita le modifiche verranno propagate dall'origine alla destinazione.
- Delegato di convalida che verrà richiamato quando viene impostato il valore della proprietà. Per altre informazioni, vedere Callback di convalida.
- Delegato modificato della proprietà che verrà richiamato quando il valore della proprietà è stato modificato. Per altre informazioni, vedere Rilevare le modifiche alle proprietà.
- Delegato che cambia proprietà che verrà richiamato quando il valore della proprietà cambierà. Questo delegato ha la stessa firma del delegato modificato della proprietà.
- Delegato di valore coerce che verrà richiamato quando il valore della proprietà è stato modificato. Per altre informazioni, vedere Callback dei valori di coerce.
- Oggetto
Func
utilizzato per inizializzare un valore di proprietà predefinito. Per altre informazioni, vedere Creare un valore predefinito con func.
Creare funzioni di accesso
Le funzioni di accesso alle proprietà sono necessarie per usare la sintassi delle proprietà per accedere a una proprietà associabile. La Get
funzione di accesso deve restituire il valore contenuto nella proprietà associabile corrispondente. A tale scopo, è possibile chiamare il GetValue
metodo , passando l'identificatore della proprietà associabile su cui ottenere il valore e quindi eseguendo il cast del risultato al tipo richiesto. La Set
funzione di accesso deve impostare il valore della proprietà associabile corrispondente. A tale scopo, è possibile chiamare il SetValue
metodo , passando l'identificatore della proprietà associabile su cui impostare il valore e il valore da impostare.
L'esempio di codice seguente mostra le funzioni di accesso per la EventName
proprietà associabile:
public string EventName
{
get { return (string)GetValue (EventNameProperty); }
set { SetValue (EventNameProperty, value); }
}
Utilizzare una proprietà associabile
Dopo aver creato una proprietà associabile, può essere utilizzata da XAML o codice. In XAML questo risultato viene ottenuto dichiarando uno spazio dei nomi con un prefisso, con la dichiarazione dello spazio dei nomi che indica il nome dello spazio dei nomi CLR e, facoltativamente, un nome di assembly. Per altre informazioni, vedere Spazi dei nomi XAML.
L'esempio di codice seguente illustra uno spazio dei nomi XAML per un tipo personalizzato che contiene una proprietà associabile, definita all'interno dello stesso assembly del codice dell'applicazione che fa riferimento al tipo personalizzato:
<ContentPage ... xmlns:local="clr-namespace:EventToCommandBehavior" ...>
...
</ContentPage>
La dichiarazione dello spazio dei nomi viene usata quando si imposta la EventName
proprietà associabile, come illustrato nell'esempio di codice XAML seguente:
<ListView ...>
<ListView.Behaviors>
<local:EventToCommandBehavior EventName="ItemSelected" ... />
</ListView.Behaviors>
</ListView>
Il codice C# equivalente è visualizzato nell'esempio seguente:
var listView = new ListView ();
listView.Behaviors.Add (new EventToCommandBehavior
{
EventName = "ItemSelected",
...
});
Scenari avanzati
Quando si crea un'istanza BindableProperty
di , è possibile impostare diversi parametri facoltativi per abilitare scenari avanzati di proprietà associabili. Questa sezione illustra questi scenari.
Rilevare le modifiche alle proprietà
Un static
metodo di callback con modifica della proprietà può essere registrato con una proprietà associabile specificando il propertyChanged
parametro per il BindableProperty.Create
metodo . Il metodo di callback specificato verrà richiamato quando viene modificato il valore della proprietà associabile.
Nell'esempio di codice seguente viene illustrato come la EventName
proprietà associabile registra il OnEventNameChanged
metodo come metodo di callback modificato dalla proprietà:
public static readonly BindableProperty EventNameProperty =
BindableProperty.Create (
"EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
...
static void OnEventNameChanged (BindableObject bindable, object oldValue, object newValue)
{
// Property changed implementation goes here
}
Nel metodo di callback con modifica della proprietà il BindableObject
parametro viene usato per indicare quale istanza della classe proprietaria ha segnalato una modifica e i valori dei due object
parametri rappresentano i valori precedenti e nuovi della proprietà associabile.
Callback di convalida
Un static
metodo di callback di convalida può essere registrato con una proprietà associabile specificando il validateValue
parametro per il BindableProperty.Create
metodo . Il metodo di callback specificato verrà richiamato quando viene impostato il valore della proprietà associabile.
Nell'esempio di codice seguente viene illustrato come la Angle
proprietà associabile registra il IsValidValue
metodo come metodo di callback di convalida:
public static readonly BindableProperty AngleProperty =
BindableProperty.Create ("Angle", typeof(double), typeof(HomePage), 0.0, validateValue: IsValidValue);
...
static bool IsValidValue (BindableObject view, object value)
{
double result;
bool isDouble = double.TryParse (value.ToString (), out result);
return (result >= 0 && result <= 360);
}
I callback di convalida vengono forniti con un valore e devono restituire true
se il valore è valido per la proprietà; in caso contrario false
, . Verrà generata un'eccezione se un callback di convalida restituisce false
, che deve essere gestito dallo sviluppatore. Un uso tipico di un metodo di callback di convalida è vincolare i valori di numeri interi o double quando viene impostata la proprietà associabile. Ad esempio, il IsValidValue
metodo verifica che il valore della proprietà sia compreso double
nell'intervallo compreso tra 0 e 360.
Callback dei valori di coesistenza
È possibile registrare un static
metodo di callback di valore coeerce con una proprietà associabile specificando il coerceValue
parametro per il BindableProperty.Create
metodo . Il metodo di callback specificato verrà richiamato quando viene modificato il valore della proprietà associabile.
Importante
Il BindableObject
tipo ha un CoerceValue
metodo che può essere chiamato per forzare una rivalutazione del valore del relativo BindableProperty
argomento, richiamando il callback del relativo valore di coercizione.
I callback dei valori di coercizione vengono usati per forzare una rivalutazione di una proprietà associabile quando il valore della proprietà cambia. Ad esempio, è possibile usare un callback di un valore di coercice per garantire che il valore di una proprietà associabile non sia maggiore del valore di un'altra proprietà associabile.
Nell'esempio di codice riportato di seguito viene illustrato come la Angle
proprietà associabile registra il CoerceAngle
metodo come metodo di callback del valore coerce:
public static readonly BindableProperty AngleProperty = BindableProperty.Create (
"Angle", typeof(double), typeof(HomePage), 0.0, coerceValue: CoerceAngle);
public static readonly BindableProperty MaximumAngleProperty = BindableProperty.Create (
"MaximumAngle", typeof(double), typeof(HomePage), 360.0, propertyChanged: ForceCoerceValue);
...
static object CoerceAngle (BindableObject bindable, object value)
{
var homePage = bindable as HomePage;
double input = (double)value;
if (input > homePage.MaximumAngle)
{
input = homePage.MaximumAngle;
}
return input;
}
static void ForceCoerceValue(BindableObject bindable, object oldValue, object newValue)
{
bindable.CoerceValue(AngleProperty);
}
Il CoerceAngle
metodo controlla il valore della proprietà e, se il Angle
valore della MaximumAngle
proprietà è maggiore di quello, il valore viene aggiunto al valore della MaximumAngle
proprietà. Inoltre, quando la MaximumAngle
proprietà modifica il callback del valore di coerce viene richiamato sulla Angle
proprietà chiamando il CoerceValue
metodo .
Creare un valore predefinito con un func
Un Func
oggetto può essere usato per inizializzare il valore predefinito di una proprietà associabile, come illustrato nell'esempio di codice seguente:
public static readonly BindableProperty SizeProperty =
BindableProperty.Create ("Size", typeof(double), typeof(HomePage), 0.0,
defaultValueCreator: bindable => Device.GetNamedSize (NamedSize.Large, (Label)bindable));
Il defaultValueCreator
parametro è impostato su un Func
oggetto che richiama il Device.GetNamedSize
metodo per restituire un double
oggetto che rappresenta le dimensioni denominate per il tipo di carattere utilizzato in una Label
nella piattaforma nativa.