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?

Techee
źródło
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ć.

HB
źródło
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");
blindmeis
źródło
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();
dotNET
źródło
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();
}
Tempeck
źródło
6

Spróbuj użyć BindingExpression.UpdateTarget()

Kushal Waikar
źródło
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();
    }
Itzdsp
źródło
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