Comment forcer une liaison WPF à s'actualiser?


112

J'ai une zone de liste déroulante avec la source des éléments attachée en utilisant une liaison simple. Existe-t-il un moyen d'actualiser cette liaison une fois la zone de liste déroulante chargée?


1
Qu'entendez-vous par simple liaison? Normalement, lorsque vous utilisez la liaison, le contrôle doit s'actualiser automatiquement.
Erno

12
Techee, pas d'offense, mais je crois que HB mérite que sa réponse soit acceptée ;-)
Dani

1
@Dani Je ne suis pas sûr que Techee revienne un jour - six ans et demi depuis qu'il est connecté
The Lonely Coder

Réponses:


198

Vous pouvez utiliser des expressions de liaison:

private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
    ((ComboBox)sender).GetBindingExpression(ComboBox.ItemsSourceProperty)
                      .UpdateTarget();
}

Mais comme Blindmeis l'a noté, vous pouvez également déclencher des notifications de changement, de plus si votre collection implémente INotifyCollectionChanged(par exemple implémentée dans le ObservableCollection<T>), elle se synchronisera afin que vous n'ayez rien à faire de cela.


Ne semble rien faire pour moi en utilisant une ListBox.
Jonathan Wood

@JonathanWood: Eh bien, je ne peux pas deviner quel type de code vous avez, y compris à quoi ressemble votre liaison. La reliure fonctionne-t-elle même en premier lieu?
HB du

56

si vous utilisez mvvm et que votre source d'éléments se trouve dans votre vm. appelez simplement INotifyPropertyChanged pour votre propriété de collection lorsque vous souhaitez actualiser.

OnPropertyChanged("YourCollectionProperty");

7
C'est l'approche la plus propre à mon humble avis.
Cendres

Cela devrait être fait dans la mesure du possible, mais il convient de noter que ce n'est pas toujours pratique. Par exemple, si vous vous connectez à un port série et que vous voulez vérifier s'il est ouvert, fermé, le débit en bauds, etc., vous pouvez créer une classe wrapper autour du port série qui implémente INotifyPropertyChanged, mais vous devrez garder le port privé pour ce wrapper et donc besoin d'écrire une propriété et une méthode pour tout sur ce port que vous utilisez ailleurs dans le projet pour vous assurer que les propriétés que vous souhaitez notifier passent toujours par le wrapper
Assimilater

8
De plus, je suis un grand fan de l'utilisation nameof(YourCollectionProperty)par opposition à une chaîne littérale. Cela empêche les bogues de refactoriser et est plus explicite ce qui est réellement prévu. C'est bien sûr là que vous ne pouvez pas utiliser l' CallerMemberNameattribut qui est encore plus agréable
Assimilater

31

Pour ajouter mes 2 cents, si vous souhaitez mettre à jour votre source de données avec la nouvelle valeur de votre Control, vous devez appeler UpdateSource()au lieu de UpdateTarget():

((TextBox)sender).GetBindingExpression(ComboBox.TextProperty).UpdateSource();

1
J'aime mieux cette réponse.
Chopnut

8

Version conviviale MultiBinding ...

private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
    BindingOperations.GetBindingExpressionBase((ComboBox)sender, ComboBox.ItemsSourceProperty).UpdateTarget();
}


0

J'étais en train de récupérer des données depuis le backend et j'ai mis à jour l'écran avec une seule ligne de code. Ça a marché. Je ne sais pas pourquoi nous devons implémenter Interface. (Windows 10, UWP)

    private void populateInCurrentScreen()
    {
        (this.FindName("Dets") as Grid).Visibility = Visibility.Visible;
        this.Bindings.Update();
    }

This.Bindings.update () actualise toutes les liaisons de l'écran. FYI
Itzdsp

J'ai essayé this.Bindings.Update () dans un contrôle utilisateur dans UWP et il n'existe pas.
James Esh

Oui. Et cela, les liaisons n'existent toujours pas.
James Esh

2
Bindings.Update () est disponible uniquement lorsque les liaisons compilées (x: Bind) sont utilisées ... et les liaisons compilées ne sont disponibles qu'en UWP
Marian Dolinský

Veuillez consulter le commentaire de @ MarianDolinský. On dirait que vous devez lier de xaml
Itzdsp
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.