Recherche…


Syntaxe

  • {Binding PropertyName} est équivalent à {Binding Path = PropertyName}
  • {Chemin de liaison = SomeProperty.SomeOtherProperty.YetAnotherProperty}
  • {Chemin de liaison = SomeListProperty [1]}

Paramètres

Paramètre Détails
Chemin Spécifie le chemin d'accès à lier. Si non spécifié, se lie au DataContext lui-même.
UpdateSourceTrigger Spécifie à quel moment la source de liaison a sa valeur mise à jour. Par défaut, LostFocus . La valeur la plus utilisée est PropertyChanged .
Mode Généralement OneWay ou TwoWay . S'il n'est pas spécifié par la liaison, sa valeur par défaut est OneWay sauf si la cible de liaison le demande comme TwoWay . Une erreur se produit lorsque TwoWay est utilisé pour se lier à une propriété en lecture seule, par exemple, OneWay doit être défini explicitement lors de la liaison d'une propriété de chaîne en lecture seule à TextBox.Text .
La source Permet d'utiliser un StaticResource comme source de liaison au lieu du DataContext actuel.
RelativeSource Permet d'utiliser un autre élément XAML comme source de liaison au lieu du DataContext actuel.
ElementName Permet d'utiliser un élément XAML nommé comme source de liaison au lieu du DataContext actuel.
Valeur de repli Si la liaison échoue, cette valeur est fournie à la cible de liaison.
TargetNullValue Si la valeur source de liaison est null , cette valeur est fournie à la cible de liaison.
Convertisseur Spécifie le convertisseur StaticResource utilisé pour convertir la valeur de la liaison, par exemple, convertir un booléen en un élément enum de Visibility .
ConvertisseurParamètre Spécifie un paramètre facultatif à fournir au convertisseur. Cette valeur doit être statique et ne peut pas être liée.
StringFormat Spécifie une chaîne de format à utiliser lors de l'affichage de la valeur liée.
Retard (WPF 4.5+) Spécifie un délai en milliseconds pendant BindingSource la liaison met à jour le BindingSource dans ViewModel . Cela doit être utilisé avec Mode=TwoWay et UpdateSourceTrigger=PropertyChanged pour prendre effet.

Remarques

UpdateSourceTrigger

Par défaut, WPF met à jour la source de liaison lorsque le contrôle perd le focus. Cependant, s'il n'y a qu'un seul contrôle capable d'obtenir le focus - quelque chose qui est courant dans les exemples - vous devrez spécifier UpdateSourceTrigger=PropertyChanged pour que les mises à jour fonctionnent.

Vous voudrez peut-être utiliser PropertyChanged comme déclencheur sur de nombreuses liaisons bidirectionnelles, à moins que la mise à jour de la source de liaison sur chaque frappe ne soit coûteuse ou que la validation des données en direct soit indésirable.

L'utilisation de LostFocus a un effet secondaire regrettable: appuyer sur Entrée pour soumettre un formulaire à l'aide d'un bouton marqué IsDefault ne met pas à jour la propriété de sauvegarde de votre liaison, annulant ainsi vos modifications. Heureusement, certaines solutions existent .

Notez également que, contrairement à UWP, WPF (4.5+) possède également la propriété Delay dans les liaisons, ce qui peut être suffisant pour certaines liaisons avec des paramètres d'intelligence mineure locale ou simple, comme certaines validations TextBox .

Convertir un booléen en valeur de visibilité

Cet exemple masque la zone rouge (bordure) si la case à cocher n'est pas cochée en utilisant un IValueConverter .

Remarque: Le BooleanToVisibilityConverter utilisé dans l'exemple ci-dessous est un convertisseur de valeur intégré situé dans l'espace de noms 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>

Définir le contexte de données

Pour pouvoir utiliser des liaisons dans WPF, vous devez définir un DataContext . Le DataContext indique aux liaisons où récupérer leurs données par défaut.

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

Vous pouvez également définir le DataContext via code-behind, mais il convient de noter que XAML IntelliSense est un peu difficile: un DataContext fortement typé doit être défini dans XAML pour que IntelliSense suggère des propriétés disponibles pour la liaison.

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

Bien qu'il existe des frameworks pour vous aider à définir votre DataContext de manière plus flexible (par exemple, MVVM Light a un localisateur de vue qui utilise l' inversion du contrôle ), nous utilisons la méthode rapide et sale pour les besoins de ce tutoriel.

Vous pouvez définir un DataContext pour pratiquement tous les éléments visuels de WPF. Le DataContext est généralement hérité des ancêtres de l’arborescence visuelle, sauf s’il a été explicitement remplacé, par exemple au sein d’un ContentPresenter.

Implémenter INotifyPropertyChanged

INotifyPropertyChanged est une interface utilisée par les sources de liaison (c.-à-d. Le DataContext) pour permettre à l'interface utilisateur ou à d'autres composants de savoir qu'une propriété a été modifiée. WPF met automatiquement à jour l'interface utilisateur lorsqu'elle détecte l'événement PropertyChanged déclenché. Il est souhaitable que cette interface soit implémentée sur une classe de base dont tous vos modèles de vues peuvent hériter.

En C # 6, c'est tout ce dont vous avez besoin:

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

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

Cela vous permet d'appeler NotifyPropertyChanged de deux manières différentes:

  1. NotifyPropertyChanged() , qui NotifyPropertyChanged() l'événement pour le setter qui l'invoque, grâce à l'attribut CallerMemberName .
  2. NotifyPropertyChanged(nameof(SomeOtherProperty)) , qui déclenchera l'événement pour SomeOtherProperty.

Pour .NET 4.5 et versions ultérieures utilisant C # 5.0, ceci peut être utilisé à la place:

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

Dans les versions de .NET antérieures à la version 4.5, vous devez définir des noms de propriété sous forme de constantes de chaîne ou une solution utilisant des expressions .


Remarque: Il est possible de lier une propriété d'un "objet C # ancien" (POCO) qui INotifyPropertyChanged pas INotifyPropertyChanged et observez que les liaisons fonctionnent mieux que prévu. Ceci est une fonctionnalité cachée dans .NET et devrait probablement être évitée. Surtout que cela entraînera des fuites de mémoire lorsque le Mode de liaison n'est pas OneTime (voir ici ).

Pourquoi la liaison est-elle mise à jour sans implémenter INotifyPropertyChanged?

Lier à la propriété d'un autre élément nommé

Vous pouvez associer une propriété à un élément nommé, mais l'élément nommé doit avoir une portée.

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

Lier à la propriété d'un ancêtre

Vous pouvez créer une liaison avec une propriété d'un ancêtre dans l'arborescence visuelle à l'aide d'une liaison RelativeSource . Le contrôle le plus proche dans l'arborescence visuelle qui a le même type ou est dérivé du type que vous spécifiez sera utilisé comme source de la liaison:

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

Dans cet exemple, Button1 a un arrière-plan gris car l'ancêtre de la Grid le plus proche a un arrière-plan gris. Button2 a un arrière-plan blanc car l'ancêtre le plus proche dérivé de FrameworkElement est le StackPanel blanc.

Exemple de liaison RelativeSource

Relier plusieurs valeurs avec un MultiBinding

MultiBinding permet de lier plusieurs valeurs à la même propriété. Dans l'exemple suivant, plusieurs valeurs sont liées à la propriété Text d'une zone de texte et mises en forme à l'aide de la propriété StringFormat.

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

En dehors de StringFormat , un IMultiValueConverter peut également être utilisé pour convertir les valeurs des liaisons en une seule valeur pour la cible du MultiBinding.

Toutefois, les MultiBindings ne peuvent pas être imbriqués.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow