Che cosa sono le dichiarazioni di associazione? (WPF .NET)

In genere, gli sviluppatori dichiarano i binding direttamente nel markup XAML degli elementi dell'interfaccia utente a cui vogliono associare i dati. Tuttavia, è anche possibile dichiarare associazioni nel codice. Questo articolo descrive come dichiarare associazioni sia in XAML che nel codice.

Prerequisiti

Prima di leggere questo articolo, è importante conoscere il concetto e l'uso delle estensioni di markup. Per altre informazioni sulle estensioni di markup, vedere Estensioni di markup e WPF XAML.

Questo articolo non tratta i concetti relativi al data binding. Per una descrizione dei concetti relativi al data binding, vedere Panoramica del data binding.

Dichiarare un'associazione in XAML

Binding è un'estensione di markup. Quando si usa l'estensione dell'associazione per dichiarare un'associazione, la dichiarazione è costituita da una serie di clausole che seguono la parola chiave Binding separate da virgole (,). Le clausole nella dichiarazione di associazione possono essere in qualsiasi ordine con molte possibili combinazioni. Le clausole sono coppie Nome=Valore, dove Name è il nome della Binding proprietà e Value è il valore che si sta impostando per la proprietà.

Durante la creazione di stringhe di dichiarazione di associazione nel markup, queste devono essere associate alla proprietà di dipendenza specifica di un oggetto di destinazione. Nell'esempio seguente viene illustrato come associare la proprietà usando l'estensione TextBox.Text di associazione, specificando le Source proprietà e Path .

<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=Name}"/>

Nell'esempio precedente viene utilizzato un tipo di oggetto dati semplice di Person. Il frammento di codice seguente è il codice per l'oggetto:

class Person
{
    public string Name { get; set; }
    public DateTime Birthdate { get; set; }
}
Public Class Person

    Public Property Name As String
    Public Property Birthdate As DateTime
    
End Class

È possibile specificare la maggior parte delle proprietà della Binding classe in questo modo. Per altre informazioni sull'estensione di associazione e per un elenco di Binding proprietà che non possono essere impostate tramite l'estensione di associazione, vedere La panoramica dell'estensione di markup di binding (.NET Framework).

Per un esempio sulla creazione di un'associazione in XAML, vedere Come creare un data binding.

Sintassi degli elementi oggetto

La sintassi degli elementi oggetto è un'alternativa alla creazione della dichiarazione di associazione. Nella maggior parte dei casi, non esiste alcun vantaggio particolare per l'uso dell'estensione di markup o della sintassi dell'elemento oggetto. Tuttavia, quando l'estensione di markup non supporta lo scenario, ad esempio quando il valore della proprietà è di un tipo non stringa per cui non esiste alcuna conversione di tipi, è necessario usare la sintassi dell'elemento oggetto.

La sezione precedente ha illustrato come eseguire il binding con un'estensione XAML. Nell'esempio seguente viene illustrata la stessa associazione, ma viene usata la sintassi dell'elemento oggetto:

<TextBlock>
    <TextBlock.Text>
        <Binding Source="{StaticResource myDataSource}" Path="Name"/>
    </TextBlock.Text>
</TextBlock>

Per altre informazioni sui diversi termini, vedere Sintassi XAML in dettaglio (.NET Framework).

MultiBinding e PriorityBinding

MultiBinding e PriorityBinding non supportano la sintassi dell'estensione XAML. Ecco perché devi usare la sintassi dell'elemento oggetto se dichiari un MultiBinding oggetto o in PriorityBinding XAML.

Creare un binding nel codice

Un altro modo per specificare un'associazione consiste nell'impostare le proprietà direttamente su un Binding oggetto nel codice e quindi assegnare l'associazione a una proprietà. Nell'esempio seguente viene illustrato come creare un Binding oggetto nel codice.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // Make a new data source object
    var personDetails = new Person()
    {
        Name = "John",
        Birthdate = DateTime.Parse("2001-02-03")
    };

    // New binding object using the path of 'Name' for whatever source object is used
    var nameBindingObject = new Binding("Name");

    // Configure the binding
    nameBindingObject.Mode = BindingMode.OneWay;
    nameBindingObject.Source = personDetails;
    nameBindingObject.Converter = NameConverter.Instance;
    nameBindingObject.ConverterCulture = new CultureInfo("en-US");

    // Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
    BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject);
}
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)

    ' Make a new data source object
    Dim personDetails As New Person() With {
        .Name = "John",
        .Birthdate = Date.Parse("2001-02-03")
    }

    ' New binding object using the path of 'Name' for whatever source object is used
    Dim nameBindingObject As New Binding("Name")

    ' Configure the binding
    nameBindingObject.Mode = BindingMode.OneWay
    nameBindingObject.Source = personDetails
    nameBindingObject.Converter = NameConverter.Instance
    nameBindingObject.ConverterCulture = New CultureInfo("en-US")

    ' Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
    BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject)

End Sub

Il codice precedente imposta quanto segue nell'associazione:

  • Percorso della proprietà nell'oggetto origine dati.
  • Modalità dell'associazione.
  • L'origine dati, in questo caso, un'istanza di oggetto semplice che rappresenta una persona.
  • Convertitore facoltativo che elabora il valore proveniente dall'oggetto origine dati prima che venga assegnato alla proprietà di destinazione.

Quando l'oggetto a cui si esegue l'associazione è o FrameworkElement FrameworkContentElement, è possibile chiamare direttamente il metodo sull'oggetto SetBinding anziché usare BindingOperations.SetBinding. Per un esempio, vedere Procedura: Creare un'associazione nel codice.

Nell'esempio precedente viene utilizzato un tipo di oggetto dati semplice di Person. Di seguito è riportato il codice per l'oggetto:

class Person
{
    public string Name { get; set; }
    public DateTime Birthdate { get; set; }
}
Public Class Person

    Public Property Name As String
    Public Property Birthdate As DateTime
    
End Class

Sintassi del percorso di associazione

Usare la Path proprietà per specificare il valore di origine a cui si vuole eseguire l'associazione:

  • Nel caso più semplice, il Path valore della proprietà è il nome della proprietà dell'oggetto di origine da utilizzare per l'associazione, ad esempio Path=PropertyName.

  • Le proprietà secondarie di una proprietà possono essere specificate da una sintassi simile a quella in C#. Ad esempio, la clausola Path=ShoppingCart.Order imposta l'associazione sulla sottoproprietà Order dell'oggetto o la proprietà ShoppingCart.

  • Per eseguire l'associazione a una proprietà associata, racchiuderla tra parentesi. Ad esempio, per eseguire l'associazione alla proprietà DockPanel.Dockassociata , la sintassi è Path=(DockPanel.Dock).

  • Gli indicizzatori di una proprietà possono essere specificati all'interno di parentesi quadre dopo il nome della proprietà in cui viene applicato l'indicizzatore. La clausola Path=ShoppingCart[0] ad esempio imposta l'associazione all'indice corrispondente al modo in cui l'indicizzazione interna della proprietà gestisce la stringa letterale "0". Sono supportati anche indicizzatori annidati.

  • Indicizzatori e sottoproprietà possono essere combinati in una clausola Path, ad esempio,Path=ShoppingCart.ShippingInfo[MailingAddress,Street].

  • All'interno degli indicizzatori. È possibile avere più parametri dell'indicizzatore separati da virgole (,). È possibile specificare tra parentesi il tipo di ogni parametro. È possibile ad esempio avere Path="[(sys:Int32)42,(sys:Int32)24]", dove è stato eseguito il mapping di sys allo spazio dei nomi System.

  • Quando l'origine è una visualizzazione raccolta, l'elemento corrente può essere specificato con una barra (/). La clausola Path=/ ad esempio imposta l'associazione all'elemento corrente nella visualizzazione. Quando l'origine è una raccolta, questa sintassi specifica l'elemento corrente della visualizzazione di raccolta predefinita.

  • Barre e nomi di proprietà possono essere combinate per attraversare le proprietà che sono raccolte. Path=/Offices/ManagerName ad esempio specifica l'elemento corrente della raccolta di origine, che contiene una proprietà Offices che è anche una raccolta. L'elemento corrente è un oggetto che contiene una proprietà ManagerName.

  • Facoltativamente, è possibile usare un percorso punto (.) per eseguire l'associazione all'origine corrente. Ad esempio, Text="{Binding}" equivale a Text="{Binding Path=.}".

Meccanismo di escape

  • All'interno degli indicizzatori ([ ]), il carattere cursore (^) esegue l'escape del carattere successivo.

  • Se imposti Path in XAML, devi anche eseguire l'escape (usando entità XML) determinati caratteri speciali per la definizione del linguaggio XML:

    • Usare &amp; per eseguire l'escape del carattere "&".

    • Usare &gt; per eseguire l'escape del tag di fine ">".

  • Inoltre, se si descrive l'intera associazione in un attributo usando la sintassi dell'estensione di markup, è necessario usare caratteri di escape (usando barra rovesciata \) caratteri speciali per il parser dell'estensione di markup WPF:

    • La barra rovesciata (\) è il carattere di escape.

    • Il segno di uguale (=) separa il nome della proprietà dal valore della proprietà.

    • La virgola (,) separa le proprietà.

    • La parentesi graffa chiusa (}) rappresenta la fine di un'estensione di markup.

Direzione di binding

Utilizzare la Binding.Mode proprietà per specificare la direzione dell'associazione. Le modalità seguenti sono le opzioni disponibili per gli aggiornamenti dell'associazione:

Modalità di binding Descrizione
BindingMode.TwoWay Aggiorna la proprietà di destinazione o la proprietà ogni volta che viene modificata la proprietà di destinazione o la proprietà di origine.
BindingMode.OneWay Aggiorna la proprietà di destinazione solo quando viene modificata la proprietà di origine.
BindingMode.OneTime Aggiorna la proprietà di destinazione solo quando l'applicazione viene avviata o quando DataContext viene sottoposta a una modifica.
BindingMode.OneWayToSource Aggiorna la proprietà di origine quando viene modificata la proprietà di destinazione.
BindingMode.Default Determina l'utilizzo del valore predefinito Mode della proprietà di destinazione.

Per altre informazioni, vedere l'enumerazione BindingMode.

Nell'esempio seguente viene illustrato come impostare la Mode proprietà :

<TextBlock Name="IncomeText" Text="{Binding Path=TotalIncome, Mode=OneTime}" />

Per rilevare le modifiche dell'origine (nel caso di binding OneWay e TwoWay), è necessario implementare un meccanismo di notifica appropriato per le modifiche delle proprietà, ad esempio INotifyPropertyChanged. Per altre informazioni, vedere Fornire notifiche di modifica.

Per TwoWay o OneWayToSource binding, è possibile controllare l'intervallo degli aggiornamenti di origine impostando la UpdateSourceTrigger proprietà . Per ulteriori informazioni, vedere UpdateSourceTrigger.

Comportamenti predefiniti

Il comportamento predefinito è il seguente se non specificato nella dichiarazione:

  • Viene creato un convertitore predefinito che tenta di eseguire una conversione di tipo tra il valore dell'origine dell'associazione e il valore della destinazione dell'associazione. Se non è possibile eseguire una conversione, il convertitore predefinito restituisce null.

  • Se non si imposta ConverterCulture, il motore di associazione usa la Language proprietà dell'oggetto di destinazione dell'associazione. In XAML questo valore predefinito è en-US o eredita il valore dall'elemento radice (o da qualsiasi elemento) della pagina, se ne è stato impostato uno in modo esplicito.

  • Purché l'associazione disponga già di un contesto dati (ad esempio, il contesto dati ereditato proveniente da un elemento padre) e qualsiasi elemento o raccolta restituito da tale contesto sia appropriato per l'associazione senza richiedere ulteriori modifiche del percorso, una dichiarazione di associazione non può avere clausole in alcun modo: {Binding}. Questo è spesso il modo in cui viene specificata un'associazione per lo stile dei dati, in cui l'associazione agisce su una raccolta. Per altre informazioni, vedere Uso di interi oggetti come origine di associazione.

  • Il valore predefinito Mode varia tra unidirezionale e bidirezionale a seconda della proprietà di dipendenza associata. È sempre possibile dichiarare in modo esplicito la modalità di associazione per garantire che il comportamento sia quello desiderato. In generale, le proprietà del controllo modificabili dall'utente, ad esempio TextBox.Text e RangeBase.Value, sono predefinite associazioni bidirezionali, ma la maggior parte delle altre proprietà viene predefinita come binding unidirezionale.

  • Il valore predefinito UpdateSourceTrigger varia anche tra PropertyChanged e LostFocus a seconda della proprietà di dipendenza associata. Il valore predefinito per la maggior parte delle proprietà di dipendenza è PropertyChanged, mentre la proprietà TextBox.Text ha il valore predefinito LostFocus.

Vedi anche