Share via


Associazioni di base

Browse sample. Esplorare l'esempio

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:

Basic code binding.

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 nome slider.
  • 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}" />

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 SourcePath, 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:

Binding context inheritance.