Modalità di binding
Ogni proprietà associabile dell'interfaccia utente dell'app multipiattaforma .NET (.NET MAUI) ha una modalità di associazione predefinita impostata quando viene creata la proprietà associabile e disponibile dalla DefaultBindingMode
proprietà dell'oggetto BindableProperty . Questa modalità di binding predefinita indica la modalità attiva quando la proprietà è una destinazione per il data binding. La modalità di binding predefinita per la maggior parte delle proprietà, come Rotation
, Scale
e Opacity
è OneWay
. Quando queste proprietà sono destinazioni per il data binding, la proprietà di destinazione è impostata dall'origine.
Nell'esempio seguente viene illustrato un data binding definito in un oggetto Slider:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.ReverseBindingPage"
Title="Reverse Binding">
<StackLayout Padding="10, 0">
<Label x:Name="label"
Text="TEXT"
FontSize="80"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Slider x:Name="slider"
VerticalOptions="Center"
Value="{Binding Source={x:Reference label},
Path=Opacity}" />
</StackLayout>
</ContentPage>
In questo esempio, Label è l'origine di data binding e Slider è la destinazione. Il binding fa riferimento alla proprietà Opacity
di Label, che ha come valore predefinito 1. Pertanto, Slider viene inizializzato sul valore 1 dal valore iniziale Opacity
di Label. Questo è illustrato nello screenshot seguente:
Inoltre, continua Slider a funzionare. Il motivo è che la modalità di associazione predefinita per la Value
proprietà di Slider è TwoWay
. Ciò significa che quando la Value
proprietà è una destinazione di data binding, la destinazione viene impostata dall'origine, ma l'origine viene impostata anche dalla destinazione. In questo modo è possibile impostare l'oggetto Slider dal valore iniziale Opacity
.
Nota
Le proprietà associabili non segnalano una modifica di proprietà a meno che la proprietà non venga effettivamente modificata. In questo modo viene impedito il ciclo infinito.
Se la modalità di associazione predefinita nella proprietà di destinazione non è adatta a un data binding specifico, è possibile eseguirne l'override impostando la proprietà di Binding
(o la Mode
proprietà dell'estensione Binding
di markup) su uno dei membri dell'enumerazioneBindingMode
:Mode
Default
TwoWay
— i dati vanno in entrambi i modi tra origine e destinazioneOneWay
— i dati passano dall'origine alla destinazioneOneWayToSource
— i dati passano da destinazione a origineOneTime
— i dati passano dall'origine alla destinazione, ma solo quando cambianoBindingContext
Associazioni bidirezionali
La maggior parte delle proprietà associabili ha una modalità di associazione predefinita di OneWay
, ma alcune proprietà hanno una modalità di associazione predefinita di TwoWay
, tra cui:
- Proprietà
Date
di DatePicker - Proprietà
Text
di Editor, Entry, SearchBar e EntryCell - Proprietà
IsRefreshing
di ListView - Proprietà
SelectedItem
diMultiPage
- Proprietà
SelectedIndex
eSelectedItem
di Picker - Proprietà
Value
di Slider e Stepper - Proprietà
IsToggled
di Switch - Proprietà
On
di SwitchCell - Proprietà
Time
di TimePicker
Queste proprietà vengono definite come TwoWay
perché quando i data binding vengono usati con il modello Model-View-ViewModel (MVVM), la classe viewmodel è l'origine del data binding e la vista, costituita da viste come Slider, sono destinazioni di data binding. Le associazioni MVVM sono simili all'esempio precedente, perché è probabile che ogni visualizzazione della pagina venga inizializzata con il valore della proprietà corrispondente nel modello di visualizzazione, ma le modifiche nella visualizzazione dovrebbero influire anche sulla proprietà viewmodel.
Associazioni unidirezionale a origine
Le proprietà con binding di sola lettura hanno la modalità di binding predefinita OneWayToSource
. Ad esempio, la SelectedItem
proprietà di ha una modalità di ListView associazione predefinita di OneWayToSource
. Ciò è dovuto al fatto che un'associazione sulla SelectedItem
proprietà deve comportare l'impostazione dell'origine dell'associazione.
Associazioni monouso
Le proprietà di destinazione con modalità di binding OneTime
vengono aggiornate solo quando il contesto di binding cambia. Per i binding in queste proprietà di destinazione, l'operazione semplifica l'infrastruttura di binding, perché non è necessario monitorare le modifiche nelle proprietà di origine.
Diverse proprietà hanno come modalità di binding predefinita OneTime
, inclusa la proprietà IsTextPredictionEnabled
di Entry.
Visualizzare modelli e notifiche di modifica delle proprietà
Quando si usa un modello di visualizzazione in un data binding, il modello di visualizzazione è l'origine del data binding. Il modello di visualizzazione non definisce proprietà associabili, ma implementa un meccanismo di notifica che consente all'infrastruttura di associazione di ricevere una notifica quando cambia il valore di una proprietà. Questo meccanismo di notifica è l'interfaccia INotifyPropertyChanged
, che definisce un singolo evento denominato PropertyChanged
. Una classe che implementa questa interfaccia genera in genere l'evento quando una delle relative proprietà pubbliche modifica il valore. L'evento non deve essere generato se la proprietà non viene mai modificata. L'interfaccia INotifyPropertyChanged
viene implementata anche da BindableObject e viene generato un PropertyChanged
evento ogni volta che una proprietà associabile cambia valore.
Nell'esempio seguente i data binding consentono di selezionare un colore usando tre Slider elementi per la tonalità, la saturazione e la luminosità:
public class HslColorViewModel : INotifyPropertyChanged
{
Color color;
string name;
float hue;
float saturation;
float luminosity;
public event PropertyChangedEventHandler PropertyChanged;
public float Hue
{
get
{
return hue;
}
set
{
if (hue != value)
{
Color = Color.FromHsla(value, saturation, luminosity);
}
}
}
public float Saturation
{
get
{
return saturation;
}
set
{
if (saturation != value)
{
Color = Color.FromHsla(hue, value, luminosity);
}
}
}
public float Luminosity
{
get
{
return luminosity;
}
set
{
if (luminosity != value)
{
Color = Color.FromHsla(hue, saturation, value);
}
}
}
public Color Color
{
get
{
return color;
}
set
{
if (color != value)
{
color = value;
hue = color.GetHue();
saturation = color.GetSaturation();
luminosity = color.GetLuminosity();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Hue"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Saturation"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Luminosity"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Color"));
Name = NamedColor.GetNearestColorName(color);
}
}
}
public string Name
{
get
{
return name;
}
private set
{
if (name != value)
{
name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
}
}
}
}
In questo esempio la classe definisce Hue
le proprietà , Luminosity
Saturation
, Color
, e Name
.HslColorViewModel
Quando uno dei tre componenti di colore cambia valore, la Color
proprietà viene ricalcolata e PropertyChanged
gli eventi vengono generati per tutte e quattro le proprietà. Quando la Color
proprietà viene modificata, il metodo statico GetNearestColorName
nella NamedColor
classe ottiene il colore denominato più vicino e imposta la Name
proprietà .
Quando un modello di visualizzazione viene impostato come origine di associazione, l'infrastruttura di associazione collega un gestore all'evento PropertyChanged
. In questo modo, l'associazione può ricevere una notifica delle modifiche alle proprietà e quindi impostare le proprietà di destinazione dai valori modificati. Tuttavia, quando una proprietà di destinazione (o la definizione Binding
in una proprietà di destinazione) ha l'elemento BindingMode
impostato su OneTime
, non è necessario per l'infrastruttura di binding associare un gestore all'evento PropertyChanged
. La proprietà di destinazione viene aggiornata solo quando cambia BindingContext
e non quando cambia la proprietà di origine stessa.
Il codice XAML seguente usa :HslColorViewModel
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataBindingDemos"
x:Class="DataBindingDemos.SimpleColorSelectorPage">
<ContentPage.BindingContext>
<local:HslColorViewModel Color="MediumTurquoise" />
</ContentPage.BindingContext>
<ContentPage.Resources>
<Style TargetType="Slider">
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
</Style>
</ContentPage.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<BoxView Color="{Binding Color}"
Grid.Row="0" />
<StackLayout Grid.Row="1"
Margin="10, 0">
<Label Text="{Binding Name}"
HorizontalTextAlignment="Center" />
<Slider Value="{Binding Hue}" />
<Slider Value="{Binding Saturation}" />
<Slider Value="{Binding Luminosity}" />
</StackLayout>
</Grid>
</ContentPage>
In questo esempio viene creata un'istanza HslColorViewModel
di e Color
la proprietà impostata e impostata come BindingContext
. BoxView, Label e tre viste Slider ereditano il contesto di binding da ContentPage. Queste viste sono tutte destinazioni di associazione che fanno riferimento alle proprietà di origine nel modello di visualizzazione. Per la Color
proprietà di BoxViewe la Text
proprietà di Label, i data binding sono OneWay
: le proprietà nella visualizzazione vengono impostate dalle proprietà nel modello di visualizzazione. La Value
proprietà dell'oggetto Slider, tuttavia, usa una TwoWay
modalità di associazione. In questo modo ogni Slider elemento può essere impostato dal modello di visualizzazione e anche per impostare il modello di visualizzazione da ogni Slideroggetto .
Quando l'esempio viene eseguito per la prima volta, , BoxViewLabele tre Slider elementi sono tutti impostati dal modello di visualizzazione in base alla proprietà iniziale Color
impostata quando è stata creata un'istanza del modello di visualizzazione:
Man mano che si modificano i dispositivi di scorrimento, e BoxView Label vengono aggiornati di conseguenza.
Override della modalità di associazione
È possibile eseguire l'override della modalità di associazione per una proprietà di destinazione impostando la proprietà di Binding
(o la Mode
proprietà dell'estensione Binding
di markup) su uno dei membri dell'enumerazioneBindingMode
.Mode
Tuttavia, l'impostazione della Mode
proprietà non produce sempre il risultato previsto. Nell'esempio seguente, ad esempio, l'impostazione della Mode
proprietà su TwoWay
non funziona come previsto:
<Label Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Scale="{Binding Source={x:Reference slider},
Path=Value,
Mode=TwoWay}" />
In questo esempio potrebbe essere previsto che l'oggetto Slider venga inizializzato nel valore iniziale della Scale
proprietà, ovvero 1, ma che non avviene. Quando un binding TwoWay
viene inizializzato, in primo luogo la destinazione viene impostata dall'origine, ovvero la proprietà Scale
viene impostata sul valore predefinito di Slider, pari a 0. Quando il binding TwoWay
è impostato per Slider, Slider viene inizialmente impostato dall'origine.
In alternativa, è possibile impostare la modalità di associazione su OneWayToSource
:
<Label Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Scale="{Binding Source={x:Reference slider},
Path=Value,
Mode=OneWayToSource}" />
Ora l'oggetto Slider viene inizializzato su 1 (il valore predefinito di Scale
) ma la Slider modifica di non influisce sulla Scale
proprietà .
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.
Un'applicazione molto utile dell'override della modalità di associazione predefinita con una TwoWay
modalità di associazione comporta la SelectedItem
proprietà di ListView. La modalità di binding predefinita è OneWayToSource
. Quando un data binding viene impostato sulla SelectedItem
proprietà per fare riferimento a una proprietà di origine in un modello di visualizzazione, tale proprietà di origine viene impostata dalla ListView selezione. Tuttavia, in alcune circostanze, potrebbe essere necessario inizializzare anche ListView dal modello di visualizzazione.
Importante
La modalità di associazione predefinita può variare da controllo a controllo e viene impostata quando viene creata la proprietà associabile. È disponibile dalla DefaultBindingMode
proprietà dell'oggetto BindableProperty .