Condividi tramite


Modalità di binding

Browse sample. Esplorare l'esempio

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:

Reverse binding.

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 destinazione
  • OneWay — i dati passano dall'origine alla destinazione
  • OneWayToSource — i dati passano da destinazione a origine
  • OneTime— i dati passano dall'origine alla destinazione, ma solo quando cambiano BindingContext

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:

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 Huele proprietà , LuminositySaturation, 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:

Simple color selector.

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 .