Przegląd deklaracji powiązań (WPF .NET)
Zazwyczaj deweloperzy deklarują powiązania bezpośrednio w znacznikach XAML elementów interfejsu użytkownika, z których 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 należy 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.
Ten artykuł nie obejmuje pojęć związanych z powiązaniem danych. Aby uzyskać omówienie pojęć związanych z powiązaniem danych, zobacz Omówienie powiązania danych.
Deklarowanie powiązania w XAML
Binding jest rozszerzeniem znaczników. Gdy używasz rozszerzenia powiązania do deklarowania powiązania, Binding deklaracja składa się z serii klauzul następujących po słocie kluczowym i rozdzielonych przecinkami (,). Klauzule w deklaracji powiązania mogą być w dowolnej kolejności i istnieje wiele możliwych kombinacji. Klauzule są parami NameValue=, gdzie NameBinding jest nazwą właściwości, a Value jest wartością ustawianą dla właściwości.
Podczas tworzenia ciągów deklaracji powiązania w znacznikach 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ć właściwość TextBox.Text przy użyciu rozszerzenia powiązania, określając właściwości Source i Path .
<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=Name}"/>
Większość właściwości klasy można określić w Binding ten sposób. Aby uzyskać więcej informacji na Binding temat rozszerzenia powiązania i listy właściwości, których nie można ustawić przy użyciu rozszerzenia powiązania, zobacz Omówienie rozszerzenia znaczników powiązania (.NET Framework).
Składnia elementu obiektu
Składnia elementu obiektu jest alternatywą dla tworzenia deklaracji powiązania. W większości przypadków użycie rozszerzenia znaczników lub składni elementu obiektu nie ma żadnej konkretnej korzyści. Jeśli jednak rozszerzenie znaczników nie obsługuje scenariusza, na przykład gdy wartość właściwości ma typ inny niż ciąg, dla którego nie istnieje konwersja typu, należy użyć składni elementu obiektu.
W poprzedniej sekcji pokazano, jak powiązać z rozszerzeniem XAML. W poniższym przykładzie pokazano wykonanie tego samego powiązania, ale użyto 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 Szczegóły składni języka XAML (.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 MultiBinding deklaruje się element lub w PriorityBinding języku XAML.
Tworzenie powiązania w kodzie
Innym sposobem określenia powiązania jest ustawienie właściwości bezpośrednio na obiekcie w kodzie, a Binding następnie przypisanie powiązania do właściwości. W poniższym przykładzie pokazano, jak utworzyć obiekt Binding 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 ustawia następujący kod w powiązaniu:
- Ścieżka właściwości obiektu źródła danych.
- Tryb powiązania.
- Źródło danych, w tym przypadku proste wystąpienie obiektu reprezentujące osobę.
- Opcjonalny konwerter, który przetwarza wartość przychodzącą z obiektu źródła danych, zanim zostanie przypisana do właściwości target.
Gdy obiektem, który jest powiązaniem, jest obiekt lub FrameworkElementFrameworkContentElement, SetBinding możesz wywołać metodę bezpośrednio w obiekcie zamiast używać metody BindingOperations.SetBinding. Aby uzyskać przykład, zobacz How to: Create a Binding in Code (Jak utworzyć powiązanie w kodzie).
W poprzednim przykładzie użyto prostego typu obiektu danych .Person Poniżej przedstawiono 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
Użyj właściwości Path , aby określić wartość źródłową, z którą chcesz powiązać:
W najprostszym przypadku wartość Path właściwości jest nazwą właściwości obiektu źródłowego do użycia dla powiązania, na przykład
Path=PropertyName.Właściwości podrzędne właściwości można określić za pomocą podobnej składni, jak w języku C#. Na przykład klauzula ustawia
Path=ShoppingCart.Orderpowiązanie na podwłaściwośćOrderobiektu lub właściwościShoppingCart.Aby powiązać element z dołączona właściwością, umieść nawiasy wokół dołączonej właściwości. Aby na przykład powiązać z dołączona 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 zastosowano indeksator. Na przykład klauzula ustawia
Path=ShoppingCart[0]powiązanie na indeks, który odpowiada sposobu obsługi ciągu literału "0" przez indeksowanie wewnętrzne właściwości. Indeksatory zagnieżdżone są również obsługiwane.Indeksery i właściwości podrzędne mogą być mieszane w klauzuli
Path, na przykładPath=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żna użyć elementuPath="[(sys:Int32)42,(sys:Int32)24]", gdziesysjest mapowane na przestrzeńSystemnazw .Gdy źródło jest widokiem kolekcji, bieżący element można określić ukośnikiem (
/). Na przykład klauzula ustawiaPath=/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 określa
Path=/Offices/ManagerNamebieżący element kolekcji źródłowej, który zawiera właściwośćOffices, która jest również kolekcją. Jego bieżącym elementem jest obiekt, który zawiera właściwośćManagerName.Opcjonalnie ścieżka okresu (
.) może służyć do powiązania z bieżącym źródłem. Na przykład instrukcjaText="{Binding}"jest równoważna instrukcjiText="{Binding Path=.}".
Mechanizm ucieczki
Wewnątrz indeksatorów (
[ ]) znak caret (^) unika następnego znaku.W przypadku ustawienia w Path języku XAML należy również użyć ucieczki (przy użyciu jednostek XML) niektórych znaków, które są specjalne dla definicji języka XML:
Użyj ,
&aby przed znakiem ucieczki "&".Użyj ,
>aby uniknąć tagu końcowego ">".
Ponadto jeśli opiszesz całe powiązanie w atlicie przy użyciu składni rozszerzenia znaczników, musisz użyć znaku ucieczki (
\przy użyciu ukośnika odwrotnego ), które są specjalne dla parsera 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 powią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 powiązania | Opis |
|---|---|
| BindingMode.TwoWay | Aktualizuje właściwość docelową lub właściwość za każdym razem, gdy właściwość docelowa lub właściwość źródłową się zmieni. |
| BindingMode.OneWay | Aktualizuje właściwość docelową tylko wtedy, gdy właściwość źródłową się zmienia. |
| BindingMode.OneTime | Aktualizuje właściwość docelową tylko wtedy, gdy aplikacja jest uruchamiana lub DataContext gdy element jest zmieniany. |
| BindingMode.OneWayToSource | Aktualizuje właściwość źródłową po zmianie właściwości docelowej. |
| BindingMode.Default | Powoduje, że Mode wartość domyślna właściwości docelowej ma być używana. |
Aby uzyskać więcej informacji, zobacz wyliczenie BindingMode .
W poniższym przykładzie pokazano, jak ustawić właściwość Mode :
<TextBlock Name="IncomeText" Text="{Binding Path=TotalIncome, Mode=OneTime}" />
Aby wykryć zmiany źródła (dotyczy powiązań OneWayTwoWay i ), źródło musi zaimplementować odpowiedni mechanizm powiadamiania o zmianie właściwości, taki jak INotifyPropertyChanged. Aby uzyskać więcej informacji, zobacz Dostarczanie powiadomień o zmianach.
W TwoWay przypadku OneWayToSource powiązań lub można kontrolować czas aktualizacji źródła, ustawiając właściwość UpdateSourceTrigger . Aby uzyskać więcej informacji, zobacz UpdateSourceTrigger.
Domyślne zachowania
Zachowanie domyślne jest następujące, jeśli nie zostanie określone w deklaracji:
Zostanie utworzony domyślny konwerter, który próbuje wykonać konwersję typu między wartością źródłową powiązania a docelową wartością powiązania. Jeśli nie można uzyskać konwersji, konwerter domyślny zwraca wartość
null.Jeśli nie ustawisz wartości ConverterCulture, aparat powiązań użyje
Languagewłaściwości obiektu docelowego powiązania. W języku XAML wartość domyślnaen-USto lub 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 dziedziczony kontekst danych z elementu nadrzędnego) i 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:
{Binding}. Jest to często sposób, w jaki powiązanie jest określane dla stylów danych, gdzie powiązanie działa na kolekcję. Aby uzyskać więcej informacji, zobacz Using Entire Objects as a Binding Source (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. Zawsze możesz jawnie zadeklarować tryb powiązania, aby upewnić się, że powiązanie ma żądane zachowanie. Ogólnie rzecz biorąc, edytowalne przez użytkownika właściwości kontrolek, TextBox.Text takie jak i RangeBase.Value, są domyślnie powiązaniami dwukierunkowymi, ale większość innych właściwości jest domyślnie łączona z powiązaniami jednokierunkowymi.
Wartość domyślna UpdateSourceTrigger różni się również LostFocusPropertyChanged w zależności od powiązanej właściwości zależności. Wartość domyślna większości właściwości zależności to PropertyChanged, a właściwość TextBox.Text ma wartość domyślną LostFocus.