Omówienie deklaracji powiązań (WPF .NET)

Zazwyczaj deweloperzy deklarują powiązania bezpośrednio w znacznikach XAML elementów interfejsu użytkownika, z którymi chcą powiązać dane. Można jednak również zadeklarować powiązania w kodzie. W tym artykule opisano sposób deklarowania powiązań zarówno w języku XAML, jak i w kodzie.

Wymagania wstępne

Przed przeczytaniem tego artykułu ważne jest, aby zapoznać się z koncepcją i użyciem rozszerzeń znaczników. Aby uzyskać więcej informacji na temat rozszerzeń znaczników, zobacz Rozszerzenia znaczników i WPF XAML.

W tym artykule nie omówiono pojęć związanych z powiązaniem danych. Aby zapoznać się z omówieniem pojęć związanych z powiązaniem danych, zobacz Omówienie powiązania danych.

Deklarowanie powiązania w języku XAML

Binding to rozszerzenie znaczników. Gdy używasz rozszerzenia powiązania do deklarowania powiązania, deklaracja składa się z serii klauzul po słowie Binding kluczowym i rozdzielonych przecinkami (,). Klauzule w deklaracji powiązania mogą być w dowolnej kolejności i istnieje wiele możliwych kombinacji. Klauzule to pary Name=Value , gdzie Name jest nazwą Binding właściwości, a Wartość jest wartością ustawianą dla właściwości.

Podczas tworzenia ciągów deklaracji powiązania w adiustacji muszą one być dołączone do określonej właściwości zależności obiektu docelowego. W poniższym przykładzie pokazano, jak powiązać TextBox.Text właściwość przy użyciu rozszerzenia powiązania, określając Source właściwości i Path .

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

Większość właściwości Binding klasy można określić w ten sposób. Aby uzyskać więcej informacji na temat rozszerzenia powiązania i listy Binding właściwości, których nie można ustawić przy użyciu rozszerzenia powiązania, zobacz Omówienie rozszerzenia powiązania znaczników (.NET Framework).

Składnia elementu object

Składnia elementu object jest alternatywą dla tworzenia deklaracji powiązania. W większości przypadków nie ma żadnej konkretnej korzyści z używania rozszerzenia znaczników lub składni elementu obiektu. Jeśli jednak rozszerzenie znaczników nie obsługuje twojego scenariusza, na przykład gdy wartość właściwości jest typu innego niż ciąg, dla którego nie istnieje konwersja typu, musisz użyć składni elementu obiektu.

W poprzedniej sekcji pokazano, jak powiązać z rozszerzeniem XAML. W poniższym przykładzie pokazano wykonywanie tego samego powiązania, ale używa składni elementu obiektu:

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

Aby uzyskać więcej informacji na temat różnych terminów, zobacz Składnia XAML w szczegółach (.NET Framework).

MultiBinding i PriorityBinding

MultiBinding i PriorityBinding nie obsługują składni rozszerzenia XAML. Dlatego należy użyć składni elementu obiektu, jeśli deklarujesz MultiBinding element lub PriorityBinding w języku XAML.

Tworzenie powiązania w kodzie

Innym sposobem określenia powiązania jest ustawienie właściwości bezpośrednio na Binding obiekcie w kodzie, a następnie przypisanie powiązania do właściwości. W poniższym przykładzie pokazano, jak utworzyć Binding obiekt w kodzie.

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

Poprzedni kod ustawił następujące elementy w powiązaniu:

  • Ścieżka właściwości obiektu źródła danych.
  • Tryb powiązania.
  • W tym przypadku źródło danych to proste wystąpienie obiektu reprezentujące osobę.
  • Opcjonalny konwerter, który przetwarza wartość pochodzącą z obiektu źródła danych przed przypisaną do właściwości docelowej.

Gdy obiekt, który jest powiązaniem, jest elementem FrameworkElementFrameworkContentElementlub , możesz wywołać SetBinding metodę bezpośrednio w obiekcie, zamiast używać metody BindingOperations.SetBinding. Aby zapoznać się z przykładem, zobacz How to: Create a Binding in Code (Instrukcje: tworzenie powiązania w kodzie).

W poprzednim przykładzie użyto prostego Persontypu obiektu danych . Poniżej znajduje się kod dla tego obiektu:

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

Składnia ścieżki powiązania

Path Użyj właściwości , aby określić wartość źródłową, z którą chcesz powiązać:

  • W najprostszym przypadku Path wartość właściwości to nazwa właściwości obiektu źródłowego do użycia dla powiązania, na przykład Path=PropertyName.

  • Podwłaściwości właściwości można określić za pomocą podobnej składni, jak w języku C#. Na przykład klauzula Path=ShoppingCart.Order ustawia powiązanie na podwłaściwość Order obiektu lub właściwości ShoppingCart.

  • Aby powiązać z dołączoną właściwością, umieść nawiasy wokół dołączonej właściwości. Na przykład aby powiązać z dołączoną właściwością DockPanel.Dock, składnia to Path=(DockPanel.Dock).

  • Indeksatory właściwości można określić w nawiasach kwadratowych po nazwie właściwości, w której jest stosowany indeksator. Na przykład klauzula Path=ShoppingCart[0] ustawia powiązanie na indeks, który odpowiada sposobie, w jaki indeksowanie wewnętrzne właściwości obsługuje ciąg literału "0". Indeksatory zagnieżdżone są również obsługiwane.

  • Indeksatory i podwłaściwości mogą być mieszane w klauzuli Path , na przykład Path=ShoppingCart.ShippingInfo[MailingAddress,Street].

  • Wewnątrz indeksatorów. Można mieć wiele parametrów indeksatora rozdzielonych przecinkami (,). Typ każdego parametru można określić za pomocą nawiasów. Na przykład możesz mieć Path="[(sys:Int32)42,(sys:Int32)24]"element , gdzie sys jest mapowany na System przestrzeń nazw.

  • Gdy źródło jest widokiem kolekcji, bieżący element można określić ukośnikiem (/). Na przykład klauzula Path=/ ustawia powiązanie na bieżący element w widoku. Gdy źródło jest kolekcją, ta składnia określa bieżący element domyślnego widoku kolekcji.

  • Nazwy właściwości i ukośniki można łączyć w celu przechodzenia przez właściwości, które są kolekcjami. Na przykład Path=/Offices/ManagerName określa bieżący element kolekcji źródłowej, który zawiera Offices również właściwość, która jest również kolekcją. Jego bieżący element jest obiektem, który zawiera ManagerName właściwość.

  • Opcjonalnie ścieżkę kropki (.) można użyć do powiązania z bieżącym źródłem. Na przykład instrukcja Text="{Binding}" jest równoważna instrukcji Text="{Binding Path=.}".

Mechanizm ucieczki

  • Wewnątrz indeksatorów ([ ]) znak karetki (^) ucieka przed następnym znakiem.

  • W przypadku ustawienia Path w języku XAML należy również użyć ucieczki (przy użyciu jednostek XML) określonych znaków specjalnych dla definicji języka XML:

    • Użyj &amp; polecenia , aby uciec od znaku "&".

    • Użyj &gt; polecenia , aby uniknąć tagu końcowego ">".

  • Ponadto, jeśli opisano całe powiązanie w atrybucie przy użyciu składni rozszerzenia znaczników, należy użyć ucieczki (przy użyciu ukośnika \odwrotnego ) znaków specjalnych dla analizatora rozszerzenia znaczników WPF:

    • Ukośnik odwrotny (\) to sam znak ucieczki.

    • Znak równości (=) oddziela nazwę właściwości od wartości właściwości.

    • Przecinek (,) oddziela właściwości.

    • Prawy nawias klamrowy (}) to koniec rozszerzenia znaczników.

Kierunek wiązania

Użyj właściwości , Binding.Mode aby określić kierunek powiązania. Dostępne są następujące tryby aktualizacji powiązań:

Tryb wiązania opis
BindingMode.TwoWay Aktualizacje właściwość docelową lub właściwość zawsze, gdy zmienia się właściwość docelowa lub właściwość źródłowa.
BindingMode.OneWay Aktualizacje właściwość docelową tylko wtedy, gdy zmienia się właściwość źródłowa.
BindingMode.OneTime Aktualizacje właściwość docelową tylko wtedy, gdy aplikacja zostanie uruchomiona lub po przejściu DataContext zmiany.
BindingMode.OneWayToSource Aktualizacje właściwość źródłowa, gdy właściwość docelowa ulegnie zmianie.
BindingMode.Default Powoduje, że wartość domyślna Mode właściwości docelowej ma być używana.

Aby uzyskać więcej informacji, zobacz BindingMode wyliczenie.

W poniższym przykładzie pokazano, jak ustawić Mode właściwość:

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

Aby wykryć zmiany źródła (dotyczy powiązań OneWay i TwoWay), źródło musi wdrożyć odpowiedni mechanizm powiadamiania o zmianie właściwości, taki jak INotifyPropertyChanged. Aby uzyskać więcej informacji, zobacz Zapewnianie powiadomień o zmianach.

W przypadku TwoWay powiązań lub OneWayToSource można kontrolować czas aktualizacji źródłowych, ustawiając UpdateSourceTrigger właściwość . W celu uzyskania więcej informacji, zobacz następujący temat: UpdateSourceTrigger.

Domyślne zachowania

Domyślne zachowanie jest następujące, jeśli nie zostanie określone w deklaracji:

  • Tworzony jest domyślny konwerter, który próbuje wykonać konwersję typu między wartością źródłową powiązania a wartością docelową powiązania. Jeśli nie można dokonać konwersji, konwerter domyślny zwraca wartość null.

  • Jeśli nie ustawisz ConverterCultureparametru , aparat powiązania używa Language właściwości obiektu docelowego powiązania. W języku XAML to ustawienie domyślne lub en-US dziedziczy wartość z elementu głównego (lub dowolnego elementu) strony, jeśli została jawnie ustawiona.

  • Jeśli powiązanie ma już kontekst danych (na przykład odziedziczony kontekst danych pochodzący z elementu nadrzędnego), a dowolny element lub kolekcja zwracana przez ten kontekst jest odpowiednia do powiązania bez konieczności dalszej modyfikacji ścieżki, deklaracja powiązania nie może mieć żadnych klauzul w ogóle: {Binding}. Jest to często sposób określenia powiązania dla stylu danych, w którym powiązanie działa na kolekcji. Aby uzyskać więcej informacji, zobacz Używanie całych obiektów jako źródła powiązania.

  • Wartość domyślna Mode różni się w zależności od powiązanej właściwości zależności jednokierunkowej i dwukierunkowej. Zawsze możesz jawnie zadeklarować tryb powiązania, aby upewnić się, że powiązanie ma żądane zachowanie. Ogólnie rzecz biorąc, właściwości kontrolki z możliwością edycji użytkownika, takie jak TextBox.Text i RangeBase.Value, domyślnie do powiązań dwukierunkowych, ale większość innych właściwości domyślnie do powiązań jednokierunkowych.

  • Wartość domyślna UpdateSourceTrigger różni się również w LostFocusPropertyChanged zależności od powiązanej właściwości zależności. Wartość domyślna dla większości właściwości zależności to PropertyChanged, a TextBox.Text właściwość ma wartość LostFocusdomyślną .

Zobacz też