Jak wymusić odświeżenie powiązania WPF?


112

Mam pole kombi z dołączonym źródłem elementów za pomocą prostego wiązania. Czy istnieje sposób, aby odświeżyć to powiązanie po załadowaniu pola kombi?


1
Co masz na myśli przez proste wiązanie? Zwykle podczas korzystania z powiązania formant powinien automatycznie odświeżyć się.
Erno

12
Techee, bez obrazy, ale uważam, że HB zasługuje na akceptację ;-)
Dani

1
@Dani Nie jestem pewien, czy Techee kiedykolwiek wróci - sześć i pół roku odkąd się zalogował
The Lonely Coder

Odpowiedzi:


198

Możesz użyć wyrażeń wiążących:

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

Ale jak zauważył Blindmeis, możesz również odpalać powiadomienia o zmianach, co więcej, jeśli twoja kolekcja implementuje INotifyCollectionChanged(na przykład zaimplementowano w ObservableCollection<T>), zsynchronizuje się, więc nie musisz tego robić.


Wydaje się, że nie robi to dla mnie za pomocą ListBox.
Jonathan Wood

@JonathanWood: Cóż, nie mogę odgadnąć, jaki masz kod, w tym jak wygląda twoje wiązanie. Czy oprawa w ogóle działa w pierwszej kolejności?
HB

56

jeśli używasz mvvm, a twoje itemsource znajduje się w twoim vm. po prostu wywołaj INotifyPropertyChanged dla swojej właściwości kolekcji, gdy chcesz odświeżyć.

OnPropertyChanged("YourCollectionProperty");

7
To najczystsze podejście imho.
Ash

Należy to zrobić w miarę możliwości, ale należy zauważyć, że nie zawsze jest to praktyczne. Na przykład, jeśli łączysz się z portem szeregowym i chcesz sprawdzić, czy jest otwarty, zamknięty, szybkość transmisji itp., Możesz utworzyć klasę opakowującą wokół portu szeregowego, który implementuje INotifyPropertyChanged, ale będziesz musiał zachować ten port jako prywatny że wrapper, a zatem trzeba napisać nieruchomości i sposób wszystko na tym porcie użyć gdzie indziej w projekcie, aby zapewnić, że właściwości jesteś zainteresowany powiadamiania na zawsze przejść przez owinięcie
Assimilater

8
Jestem też wielkim fanem używania nameof(YourCollectionProperty)w przeciwieństwie do dosłownego ciągu. Zapobiega to refaktoryzacji błędów i jest bardziej jasne, co jest faktycznie zamierzone. Tutaj oczywiście nie można użyć CallerMemberNameatrybutu, który jest jeszcze ładniejszy
Assimilater

31

Aby dodać moje 2 centy, jeśli chcesz zaktualizować swoje źródło danych o nową wartość swojej Kontroli, musisz zadzwonić UpdateSource()zamiast UpdateTarget():

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

1
Ta odpowiedź podoba mi się bardziej.
Chopnut

8

Wersja przyjazna dla MultiBinding ...

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


0

Pobierałem dane z zaplecza i aktualizowałem ekran za pomocą tylko jednej linii kodu. Zadziałało. Nie jestem pewien, dlaczego musimy wdrożyć Interface. (Windows 10, UWP)

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

This.Bindings.update () odświeża wszystkie powiązania na ekranie. FYI
Itzdsp

Próbowałem this.Bindings.Update () w kontroli użytkownika w UWP i nie istnieje.
James Esh

Tak. I to Wiązania nadal nie istnieją.
James Esh

2
Bindings.Update () jest dostępna tylko wtedy, gdy używane są skompilowane powiązania (x: Bind) ... a skompilowane powiązania są dostępne tylko w UWP
Marian Dolinský

Proszę spojrzeć na komentarz @ MarianDolinský. Wygląda na to, że musisz związać się z
XAML
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.