Zoeken…


Syntaxis

  • {Binding PropertyName} is gelijk aan {Binding Path = PropertyName}
  • {Binding Path = SomeProperty.SomeOtherProperty.YetAnotherProperty}
  • {Binding Path = SomeListProperty [1]}

parameters

Parameter Details
Pad Hiermee geeft u het pad op waaraan u wilt binden. Indien niet gespecificeerd, bindt aan de DataContext zelf.
UpdateSourceTrigger Geeft aan wanneer de waarde van de bindende bron wordt bijgewerkt. Standaard ingesteld op LostFocus . De meest gebruikte waarde is PropertyChanged .
mode Meestal OneWay of TwoWay . Indien niet gespecificeerd door de binding, wordt standaard OneWay tenzij het bindende doel vraagt om TwoWay . Er treedt een fout op wanneer TwoWay wordt gebruikt om een readonly-eigenschap te binden, bijv. OneWay moet expliciet worden ingesteld bij het binden van een readonly- TextBox.Text aan TextBox.Text .
Bron Staat het gebruik van een StaticResource als een bindende bron in plaats van de huidige DataContext.
RelativeSource Staat het gebruik van een ander XAML-element toe als een bindende bron in plaats van de huidige DataContext.
ElementName Staat het gebruik van een benoemd XAML-element toe als een bindende bron in plaats van de huidige DataContext.
FallbackValue Als de binding mislukt, wordt deze waarde aan het bindende doel gegeven.
TargetNullValue Als de bindende bronwaarde null , wordt deze waarde aan het bindende doel verstrekt.
omvormer Hiermee geeft u de converter StaticResource die wordt gebruikt om de waarde van de binding te converteren, bijvoorbeeld een Boolean naar een Enum-item voor Visibility omzetten.
ConverterParameter Hiermee geeft u een optionele parameter op die aan de converter moet worden verstrekt. Deze waarde moet statisch zijn en kan niet worden gebonden.
StringFormat Hiermee geeft u een opmaakreeks op die moet worden gebruikt bij het weergeven van de gebonden waarde.
Vertraging (WPF 4.5+) Geeft een vertraging in milliseconds voor de binding om de BindingSource in het ViewModel . Dit moet worden gebruikt met Mode=TwoWay en UpdateSourceTrigger=PropertyChanged om van kracht te worden.

Opmerkingen

UpdateSourceTrigger

Standaard werkt WPF de bindende bron bij wanneer het besturingselement de focus verliest. Als er echter maar één besturingselement is dat focus kan krijgen - iets dat gebruikelijk is in voorbeelden - moet u UpdateSourceTrigger=PropertyChanged opgeven om de updates te laten werken.

U zult PropertyChanged willen gebruiken als de trigger voor veel tweerichtingsbindingen, tenzij het bijwerken van de bindende bron bij elke toetsaanslag duur is of live gegevensvalidatie ongewenst is.

Het gebruik van LostFocus heeft een ongelukkig neveneffect: als u op Enter drukt om een formulier in te dienen met de knop IsDefault wordt de eigenschap die uw binding ondersteunt niet bijgewerkt en worden uw wijzigingen effectief ongedaan gemaakt. Gelukkig bestaan er enkele oplossingen .

Houd er ook rekening mee dat, in tegenstelling tot UWP, WPF (4.5+) ook de eigenschap Delay in bindingen heeft, wat misschien net genoeg is voor sommige bindingen met alleen lokale of eenvoudige, kleine intelligentie-instellingen, zoals sommige TextBox validaties.

Converteer een Booleaanse waarde naar zichtbaarheidswaarde

In dit voorbeeld wordt het rode vakje (rand) verborgen als het selectievakje niet is ingeschakeld met behulp van een IValueConverter .

Opmerking: De BooleanToVisibilityConverter die in het onderstaande voorbeeld wordt gebruikt, is een ingebouwde BooleanToVisibilityConverter in de naamruimte 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>

Gegevenscontext definiëren

Om met bindingen in WPF te werken, moet u een DataContext definiëren. De DataContext vertelt bindingen waar ze hun gegevens standaard vandaan kunnen halen.

<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>

U kunt de DataContext ook instellen via code-behind, maar het is vermeldenswaard dat XAML IntelliSense ietwat kieskeurig is: een sterk getypte DataContext moet in XAML worden ingesteld voor IntelliSense om eigenschappen te suggereren die beschikbaar zijn voor binding.

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

Hoewel er frameworks zijn om u te helpen uw DataContext op een flexibelere manier te definiëren (bijv. MVVM Light heeft een viewmodel-locator die inversie van controle gebruikt ), gebruiken we de snelle en vuile methode voor de doeleinden van deze tutorial.

U kunt een DataContext definiëren voor vrijwel elk visueel element in WPF. De DataContext wordt over het algemeen geërfd van voorouders in de visuele structuur, tenzij deze expliciet is overschreven, bijvoorbeeld in een ContentPresenter.

Implementeren van INotifyPropertyChanged

INotifyPropertyChanged is een interface die wordt gebruikt door bindende bronnen (dat wil zeggen de DataContext) om de gebruikersinterface of andere componenten te laten weten dat een eigenschap is gewijzigd. WPF werkt de gebruikersinterface automatisch voor u bij wanneer de PropertyChanged gebeurtenis wordt verhoogd. Het is wenselijk om deze interface te implementeren op een basisklasse waarvan al uw viewmodels kunnen erven.

In C # 6 is dit alles wat je nodig hebt:

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

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

Dit stelt u in staat om NotifyPropertyChanged op twee verschillende manieren aan te roepen:

  1. NotifyPropertyChanged() , waardoor het evenement wordt NotifyPropertyChanged() voor de setter die het oproept, dankzij het kenmerk CallerMemberName .
  2. NotifyPropertyChanged(nameof(SomeOtherProperty)) , waardoor het evenement voor SomeOtherProperty wordt verhoogd.

Voor .NET 4.5 en hoger met C # 5.0 kan dit in plaats daarvan worden gebruikt:

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));
        }
    }
}

In versies van .NET die ouder zijn dan 4.5, moet u genoegen nemen met eigenschapsnamen als tekenreeksconstanten of een oplossing met expressies .


Opmerking: Het is mogelijk om te binden aan een eigenschap van een "gewoon oud C # object" (POCO) dat INotifyPropertyChanged niet implementeert en te observeren dat de bindingen beter werken dan verwacht. Dit is een verborgen functie in .NET en moet waarschijnlijk worden vermeden. Vooral omdat het geheugenlekken veroorzaakt wanneer de Mode de binding niet OneTime (zie hier ).

Waarom wordt de bindende update uitgevoerd zonder INotifyPropertyChanged te implementeren?

Binden aan eigenschap van een ander benoemd element

U kunt binden aan een eigenschap van een benoemd element, maar het genoemde element moet binnen bereik zijn.

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

Binden aan eigendom van een voorouder

U kunt binden aan een eigenschap van een voorouder in de visuele structuur met behulp van een RelativeSource binding. Het dichtstbijzijnde besturingselement hoger in de visuele structuur dat hetzelfde type heeft of is afgeleid van het type dat u opgeeft, wordt gebruikt als de bron van de binding:

<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>

In dit voorbeeld heeft Button1 een grijze achtergrond omdat de dichtstbijzijnde Grid voorouder een grijze achtergrond heeft. Button2 heeft een witte achtergrond omdat de dichtstbijzijnde voorouder afgeleid van FrameworkElement de witte StackPanel .

Relatief bron bindend voorbeeld

Meerdere waarden binden met een MultiBinding

Met MultiBinding kunnen meerdere waarden aan dezelfde eigenschap worden gekoppeld. In het volgende voorbeeld zijn meerdere waarden gebonden aan de eigenschap Text van een Textbox en opgemaakt met de eigenschap StringFormat.

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

Naast StringFormat kan een IMultiValueConverter ook worden gebruikt om de waarden van de bindingen om te zetten in één waarde voor het doel van de MultiBinding.

MultiBindings kunnen echter niet worden genest.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow