Associazioni di base
Un'interfaccia utente dell'app multipiattaforma .NET (.NET MAUI) collega una coppia di proprietà tra due oggetti, almeno una delle quali è in genere un oggetto interfaccia utente. Questi due oggetti vengono chiamati destinazione e origine:
- La destinazione è l'oggetto (e la proprietà) su cui è impostato il data binding.
- L'origine è l'oggetto (e la proprietà) a cui fa riferimento il data binding.
Nel caso più semplice, i dati passano dall'origine alla destinazione. Ciò significa che il valore della proprietà di destinazione è impostato dal valore della proprietà di origine. Tuttavia in alcuni casi i dati possono passare dalla destinazione all'origine o in entrambe le direzioni.
Importante
La destinazione è sempre l'oggetto su cui è impostato il data binding anche se fornisce dati anziché ricevere dati.
Associazioni con un contesto di associazione
Si consideri l'esempio XAML seguente, la cui finalità consiste nel ruotare un oggetto Label modificando un oggetto Slider:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.BasicCodeBindingPage"
Title="Basic Code Binding">
<StackLayout Padding="10, 0">
<Label x:Name="label"
Text="TEXT"
FontSize="48"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Slider x:Name="slider"
Maximum="360"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
Senza i data binding sarebbe necessario impostare l'evento ValueChanged
di Slider su un gestore eventi che accede alla proprietà Value
di Slider e imposta tale valore sulla proprietà Rotation
di Label. Il data binding automatizza questa attività e quindi il gestore eventi e il codice al suo interno non sono più necessari.
È possibile impostare un binding su un'istanza di qualsiasi classe derivata da BindableObject, che include i derivati Element, VisualElement, View e View. Il binding è sempre impostato sull'oggetto di destinazione. Il binding fa riferimento all'oggetto di origine. Per impostare il data binding usare i due membri seguenti della classe di destinazione:
- La proprietà
BindingContext
specifica l'oggetto di origine. - Il metodo
SetBinding
specifica la proprietà di destinazione e la proprietà di origine.
In questo esempio, Label è la destinazione del binding e Slider è l'origine del binding. Le modifiche nell'origine Slider hanno effetto sulla rotazione della destinazione Label. I dati passano dall'origine alla destinazione.
Il metodo SetBinding
definito da BindableObject ha un argomento di tipo BindingBase
da cui deriva la classe Binding
, ma sono presenti altri metodi SetBinding
definiti dalla classe BindableObjectExtensions
. Il code-behind per XAML usa un metodo di estensione più semplice SetBinding
dalla BindableObjectExtensions
classe :
public partial class BasicCodeBindingPage : ContentPage
{
public BasicCodeBindingPage()
{
InitializeComponent();
label.BindingContext = slider;
label.SetBinding(Label.RotationProperty, "Value");
}
}
L'oggetto Label è la destinazione del binding, ovvero l'oggetto sul quale è impostata questa proprietà e sul quale viene chiamato il metodo. La proprietà BindingContext
indica l'origine del binding, ovvero Slider. Il metodo SetBinding
viene chiamato sulla destinazione del binding, ma specifica sia la proprietà di destinazione che la proprietà di origine. La proprietà di destinazione viene specificata come oggetto BindableProperty: Label.RotationProperty
. La proprietà di origine viene specificata come stringa e indica la proprietà Value
di Slider.
Importante
La proprietà di destinazione deve essere supportata da una proprietà con binding. Pertanto, l'oggetto di destinazione deve essere un'istanza di una classe che deriva da BindableObject. Per altre informazioni, vedere Proprietà associabili.
La proprietà di origine viene specificata come stringa. A livello interno, per l'accesso alla proprietà viene usata una reflection. In questo caso specifico, tuttavia, la proprietà Value
è anche supportata da una proprietà con binding.
Quando si aziona l'elemento Slider, l'elemento Label ruota di conseguenza:
In alternativa, il data binding può essere specificato in XAML:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.BasicXamlBindingPage"
Title="Basic XAML Binding">
<StackLayout Padding="10, 0">
<Label Text="TEXT"
FontSize="80"
HorizontalOptions="Center"
VerticalOptions="Center"
BindingContext="{x:Reference Name=slider}"
Rotation="{Binding Path=Value}" />
<Slider x:Name="slider"
Maximum="360"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
Come nel codice, il data binding è impostato sull'oggetto di destinazione, ovvero su Label. Per definire il data binding vengono usate due estensioni di markup XAML:
- L'estensione di markup
x:Reference
è obbligatoria per il riferimento all'oggetto di origine, ovvero l'elemento Slider con nomeslider
. - L'estensione di markup
Binding
collega la proprietàRotation
di Label alla proprietàValue
di Slider.
Per altre informazioni sulle estensioni di markup XAML, vedi Utilizzare estensioni di markup XAML.
Nota
La proprietà di origine viene specificata con la Path
proprietà dell'estensione Binding
di markup, che corrisponde alla Path
proprietà della Binding
classe .
le estensioni di markup XAML come x:Reference
e Binding
possono avere attributi content property definiti. Per le estensioni di markup XAML ciò significa che non è necessario che sia visualizzato il nome della proprietà. La proprietà Name
è la proprietà di contenuto di x:Reference
, mentre la proprietà Path
è la proprietà di contenuto di Binding
. Questo significa che entrambe possono essere eliminate delle espressioni:
<Label Text="TEXT"
FontSize="80"
HorizontalOptions="Center"
VerticalOptions="Center"
BindingContext="{x:Reference slider}"
Rotation="{Binding Value}" />
Importante
Le prestazioni dell'associazione possono essere migliorate usando le associazioni compilate. Per altre informazioni, vedere Binding compilati.
Associazioni senza contesto di associazione
La proprietà BindingContext
è un componente importante per i data binding, ma non è sempre necessaria. L'oggetto di origine può invece essere specificato nella SetBinding
chiamata o nell'estensione di Binding
markup:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.AlternativeCodeBindingPage"
Title="Alternative Code Binding">
<StackLayout Padding="10, 0">
<Label x:Name="label"
Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Slider x:Name="slider"
Minimum="-2"
Maximum="2"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
In questo esempio l'oggetto Slider viene definito per controllare la Scale
proprietà dell'oggetto Label. Per questo motivo, Slider viene impostato per un intervallo compreso tra -2 e 2.
Il file code-behind imposta l'associazione con il SetBinding
metodo , con il secondo argomento che rappresenta un costruttore per la Binding
classe :
public partial class AlternativeCodeBindingPage : ContentPage
{
public AlternativeCodeBindingPage()
{
InitializeComponent();
label.SetBinding(Label.ScaleProperty, new Binding("Value", source: slider));
}
}
Il costruttore Binding
ha 6 parametri, pertanto il parametro source
è specificato con un argomento denominato. L'argomento è l'oggetto slider
.
Nota
La classe VisualElement definisce anche le proprietà ScaleX
e ScaleY
, che possono modificare in scala VisualElement in modi diversi in direzione orizzontale e verticale.
In alternativa, il data binding può essere specificato in XAML:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.AlternativeXamlBindingPage"
Title="Alternative XAML Binding">
<StackLayout Padding="10, 0">
<Label Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="Center"
Scale="{Binding Source={x:Reference slider},
Path=Value}" />
<Slider x:Name="slider"
Minimum="-2"
Maximum="2"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
In questo esempio, l'estensione Binding
di markup ha due proprietà impostate e Source
Path
, separate da una virgola. La proprietà Source
è impostata su un'estensione di markup x:Reference
incorporata, che per il resto ha la stessa sintassi dell'impostazione di BindingContext
.
La proprietà del contenuto dell'estensione di markup Binding
è Path
, ma la parte Path=
dell'estensione di markup può essere eliminata solo se è la prima proprietà nell'espressione. Per eliminare la parte Path=
è necessario scambiare le due proprietà:
Scale="{Binding Value, Source={x:Reference slider}}" />
Le estensioni di markup XAML sono in genere delimitate da parentesi graffe, ma possono anche essere espresse come elementi oggetto:
<Label Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="Center">
<Label.Scale>
<Binding Source="{x:Reference slider}"
Path="Value" />
</Label.Scale>
</Label>
In questo esempio le Source
proprietà e Path
sono attributi XAML normali. i valori vengono visualizzati racchiusi tra virgolette e gli attributi non sono separati da una virgola. Anche l'estensione di markup x:Reference
può trasformarsi in un elemento oggetto:
<Label Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="Center">
<Label.Scale>
<Binding Path="Value">
<Binding.Source>
<x:Reference Name="slider" />
</Binding.Source>
</Binding>
</Label.Scale>
</Label>
Questa sintassi non è comune, ma può risultare necessaria in presenza di oggetti complessi.
Gli esempi illustrati finora impostano la proprietà BindingContext
e la proprietà Source
di Binding
su un'estensione di markup x:Reference
per fare riferimento a un'altra visualizzazione nella pagina. Queste due proprietà sono di tipo Object
e possono essere impostate su qualsiasi oggetto che include proprietà adatte alle origini di binding. È anche possibile impostare la BindingContext
proprietà o Source
su un'estensione x:Static
di markup per fare riferimento al valore di una proprietà o di un campo statico oppure a un'estensione StaticResource
di markup per fare riferimento a un oggetto archiviato in un dizionario risorse o direttamente a un oggetto, che spesso è un'istanza di un modello di visualizzazione.
Nota
La proprietà BindingContext
può anche essere impostata su un oggetto Binding
in modo che le proprietà Source
e Path
di Binding
definiscano il contesto di binding.
Ereditarietà del contesto di associazione
È possibile specificare l'oggetto di origine utilizzando la BindingContext
proprietà o la Source
proprietà dell'oggetto Binding
. Se sono impostate entrambe, la proprietà Source
di Binding
ha la precedenza su BindingContext
.
Importante
Il valore della BindingContext
proprietà viene ereditato tramite la struttura ad albero visuale.
L'esempio XAML seguente illustra l'ereditarietà del contesto di associazione:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.BindingContextInheritancePage"
Title="BindingContext Inheritance">
<StackLayout Padding="10">
<StackLayout VerticalOptions="Fill"
BindingContext="{x:Reference slider}">
<Label Text="TEXT"
FontSize="80"
HorizontalOptions="Center"
VerticalOptions="End"
Rotation="{Binding Value}" />
<BoxView Color="#800000FF"
WidthRequest="180"
HeightRequest="40"
HorizontalOptions="Center"
VerticalOptions="Start"
Rotation="{Binding Value}" />
</StackLayout>
<Slider x:Name="slider"
Maximum="360" />
</StackLayout>
</ContentPage>
In questo esempio la BindingContext
proprietà di StackLayout è impostata sull'oggetto slider
. Questo contesto di binding viene ereditato sia da Label che da BoxView e le proprietà Rotation
di entrambi sono impostate sulla proprietà Value
di Slider: