Szukaj…


Składnia

  • {Binding PropertyName} odpowiada {Binding Path = PropertyName}
  • {Binding Path = SomeProperty.SomeOtherProperty.YetAnotherProperty}
  • {Binding Path = SomeListProperty [1]}

Parametry

Parametr Detale
Ścieżka Określa ścieżkę do powiązania. Jeśli nie jest określony, wiąże się z samym DataContext.
UpdateSourceTrigger Określa, kiedy wartość źródła wiązania ma zostać zaktualizowana. Domyślnie LostFocus . Najczęściej używana wartość to PropertyChanged .
Tryb Zazwyczaj OneWay lub TwoWay . Jeśli nie jest określone przez powiązanie, domyślnie jest ustawione na OneWay chyba że cel powiązania zażąda, aby to był TwoWay . Błąd występuje, gdy TwoWay jest używany do wiązania właściwości tylko do odczytu, np. OneWay musi być jawnie ustawiony podczas wiązania właściwości ciągu tylko do odczytu z TextBox.Text .
Źródło Pozwala na użycie StaticResource jako źródła powiązania zamiast bieżącego DataContext.
RelativeSource Pozwala na użycie innego elementu XAML jako źródła wiązania zamiast bieżącego DataContext.
ElementName Pozwala na użycie nazwanego elementu XAML jako źródła powiązania zamiast bieżącego DataContext.
FallbackValue Jeśli powiązanie nie powiedzie się, ta wartość jest przekazywana do celu powiązania.
TargetNullValue Jeśli wartość źródła wiązania jest równa null , wartość ta jest przekazywana do obiektu docelowego wiązania.
Przetwornik Określa konwerter StaticResource który służy do konwersji wartości powiązania, np. Przekształca wartość logiczną na element wyliczający Visibility .
ConverterParameter Określa opcjonalny parametr, który należy podać konwerterowi. Ta wartość musi być statyczna i nie może być powiązana.
StringFormat Określa ciąg formatu, który będzie używany podczas wyświetlania powiązanej wartości.
Opóźnienie (WPF 4.5+) Określa opóźnienie w milliseconds dla powiązania w celu zaktualizowania BindingSource w ViewModel . Musi być użyte z Mode=TwoWay i UpdateSourceTrigger=PropertyChanged aby UpdateSourceTrigger=PropertyChanged .

Uwagi

UpdateSourceTrigger

Domyślnie WPF aktualizuje źródło wiązania, gdy formant traci fokus. Jeśli jednak istnieje tylko jeden element sterujący, na którym można skupić się - co jest powszechne w przykładach - konieczne będzie określenie UpdateSourceTrigger=PropertyChanged aby aktualizacje działały.

Będziesz chciał użyć PropertyChanged jako wyzwalacza w wielu powiązaniach dwukierunkowych, chyba że aktualizacja źródła powiązania przy każdym naciśnięciu klawisza jest kosztowna lub sprawdzanie poprawności danych na żywo jest niepożądane.

Korzystanie z LostFocus ma niefortunny efekt uboczny: naciśnięcie Enter, aby przesłać formularz za pomocą przycisku oznaczonego IsDefault , nie aktualizuje właściwości wspierającej wiązanie, skutecznie cofając zmiany. Na szczęście istnieją pewne obejścia .

Należy również pamiętać, że w przeciwieństwie do UWP, WPF (4.5+) ma również właściwość Delay w powiązaniach, która może być wystarczająca dla niektórych powiązań z lokalnymi lub prostymi niewielkimi ustawieniami inteligencji, takimi jak niektóre weryfikacje TextBox .

Konwertuj wartość logiczną na wartość widoczności

Ten przykład ukrywa czerwone pole (ramkę), jeśli pole wyboru nie jest zaznaczone przy użyciu IValueConverter .

Uwaga: BooleanToVisibilityConverter zastosowany w poniższym przykładzie jest wbudowanym konwerterem wartości, znajdującym się w przestrzeni nazw System.Windows.Controls.

XAML:

<Window x:Class="StackOverflowDataBindingExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="VisibleIfTrueConverter" />
    </Window.Resources>
    <StackPanel>
        <CheckBox x:Name="MyCheckBox"
                  IsChecked="True" />
        <Border Background="Red" Width="20" Height="20"
                Visibility="{Binding Path=IsChecked,ElementName=MyCheckBox, Converter={StaticResource VisibleIfTrueConverter}}" />
    </StackPanel>
</Window>

Definiowanie DataContext

Aby pracować z powiązaniami w WPF, musisz zdefiniować DataContext . DataContext domyślnie informuje powiązania, skąd mają pobierać swoje dane.

<Window x:Class="StackOverflowDataBindingExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:StackOverflowDataBindingExample"
        xmlns:vm="clr-namespace:StackOverflowDataBindingExample.ViewModels"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <vm:HelloWorldViewModel />
    </Window.DataContext>
    ...
</Window>

Możesz również ustawić DataContext za pomocą kodu, ale warto zauważyć, że XAML IntelliSense jest nieco wybredny: silnie typowany DataContext musi być ustawiony w XAML dla IntelliSense, aby zasugerować właściwości dostępne do wiązania.

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new HelloWorldViewModel();
    }
}

Chociaż istnieją ramy pomagające zdefiniować DataContext w bardziej elastyczny sposób (np. MVVM Light ma lokalizator viewmodel, który wykorzystuje odwrócenie kontroli ), do celów tego samouczka używamy szybkiej i brudnej metody.

Możesz zdefiniować DataContext dla praktycznie dowolnego elementu wizualnego w WPF. DataContext jest generalnie dziedziczony od przodków w drzewie wizualnym, chyba że został wyraźnie zastąpiony, np. W ContentPresenter.

Implementowanie INotifyPropertyChanged

INotifyPropertyChanged to interfejs używany przez źródła powiązań (tj. DataContext), aby powiadomić interfejs użytkownika lub inne komponenty o zmianie właściwości. WPF automatycznie aktualizuje interfejs użytkownika, gdy zobaczy podniesione zdarzenie PropertyChanged . Pożądane jest, aby interfejs ten został zaimplementowany w klasie bazowej, z której wszystkie twoje modele viewmode mogą dziedziczyć.

W C # 6 to wszystko, czego potrzebujesz:

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

Umożliwia to wywołanie NotifyPropertyChanged na dwa różne sposoby:

  1. NotifyPropertyChanged() , który wywoła zdarzenie dla NotifyPropertyChanged() , który je wywołuje, dzięki atrybutowi CallerMemberName .
  2. NotifyPropertyChanged(nameof(SomeOtherProperty)) , który wywoła zdarzenie dla SomeOtherProperty.

W przypadku .NET 4.5 i nowszych przy użyciu C # 5.0 można tego użyć:

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName] string name = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

W wersjach .NET wcześniejszych niż 4.5, musisz zadowolić się nazwami właściwości jako stałymi łańcuchowymi lub rozwiązaniem wykorzystującym wyrażenia .


Uwaga: Możliwe jest powiązanie z właściwością „zwykłego starego obiektu C #” (POCO), który nie implementuje INotifyPropertyChanged i zaobserwowanie, że wiązania działają lepiej niż oczekiwano. Jest to ukryta funkcja w .NET i prawdopodobnie należy jej unikać. Zwłaszcza, że spowoduje to wycieki pamięci, gdy Mode powiązania nie jest OneTime (patrz tutaj ).

Dlaczego wiązanie aktualizuje się bez implementacji INotifyPropertyChanged?

Powiązanie z właściwością innego nazwanego elementu

Można powiązać z właściwością na nazwanym elemencie, ale nazwany element musi mieć zasięg.

<StackPanel>
    <CheckBox x:Name="MyCheckBox" IsChecked="True" />
    <TextBlock Text="{Binding IsChecked, ElementName=MyCheckBox}" />
</StackPanel>

Powiązanie z własnością przodka

Można powiązać z właściwością przodka w drzewie wizualnym za pomocą powiązania RelativeSource . Najbliższa kontrolka wyżej w drzewie wizualnym, która ma ten sam typ lub pochodzi od określonego typu, zostanie użyta jako źródło powiązania:

<Grid Background="Blue">
    <Grid Background="Gray" Margin="10">
        <Border Background="Red" Margin="20">
            <StackPanel Background="White" Margin="20">
                <Button Margin="10" Content="Button1" Background="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}}" />
                <Button Margin="10" Content="Button2" Background="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}}" />
            </StackPanel>
        </Border>
    </Grid>
</Grid>

W tym przykładzie Button1 ma szare tło, ponieważ najbliższy przodek Grid ma szare tło. Button2 ma białe tło, ponieważ najbliższym przodkiem pochodzącym z FrameworkElement jest biały StackPanel .

Przykład powiązania RelativeSource

Wiązanie wielu wartości za pomocą funkcji MultiBinding

Funkcja MultiBinding umożliwia powiązanie wielu wartości z tą samą właściwością. W poniższym przykładzie wiele wartości jest powiązanych z właściwością Text pola tekstowego i sformatowanych przy użyciu właściwości StringFormat.

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{0} {1}">
            <Binding Path="User.Forename"/>
            <Binding Path="User.Surname"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

Oprócz StringFormat An IMultiValueConverter może być również stosowany do przeliczenia wartości z wiązaniami do jednej wartości dla realizacji celu MultiBinding użytkownika.

Jednak MultiBindings nie może być zagnieżdżony.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow