Come forzare l'aggiornamento di un'associazione WPF?


112

Ho una casella combinata con la fonte degli elementi allegata utilizzando l'associazione semplice. C'è un modo per aggiornare questa associazione una volta caricata la casella combinata?


1
Cosa intendi per rilegatura semplice? Normalmente, quando si utilizza l'associazione, il controllo dovrebbe aggiornarsi automaticamente.
Erno

12
Techee, senza offesa, ma credo che HB meriti la sua risposta per essere accettata ;-)
Dani

1
@Dani Non sono sicuro che Techee tornerà mai - sei anni e mezzo da quando ha effettuato l'accesso
The Lonely Coder

Risposte:


198

Puoi usare espressioni di associazione:

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

Ma come ha notato Blindmeis puoi anche attivare le notifiche di modifica, inoltre se la tua raccolta implementa INotifyCollectionChanged(ad esempio implementata in ObservableCollection<T>) si sincronizzerà, quindi non è necessario fare nulla di tutto ciò.


Non sembra fare nulla per me usando un ListBox.
Jonathan Wood

@ JonathanWood: Beh, non posso indovinare che tipo di codice hai, incluso l'aspetto del tuo binding. La rilegatura funziona anche in primo luogo?
HB

56

se usi mvvm e il tuo itemssource si trova nel tuo vm. basta chiamare INotifyPropertyChanged per la proprietà della raccolta quando si desidera aggiornare.

OnPropertyChanged("YourCollectionProperty");

7
Questo è l'approccio più pulito imho.
Ash

Questo dovrebbe essere fatto ove possibile, ma va notato che non è sempre pratico. Ad esempio, se ti stai associando a una porta seriale e vuoi controllare se è aperta, chiusa, la velocità di trasmissione, ecc. Puoi creare una classe wrapper attorno alla porta seriale che implementa INotifyPropertyChanged, ma dovrai mantenere la porta privata per quel wrapper e quindi devi scrivere una proprietà e un metodo per tutto su quella porta che usi altrove nel progetto per assicurarti che le proprietà su cui sei interessato a notificare passino sempre attraverso il wrapper
Assimilater

8
Inoltre, sono un grande fan dell'uso nameof(YourCollectionProperty)al contrario di una stringa letterale. Ciò impedisce il refactoring dei bug ed è più esplicito ciò che è effettivamente inteso. Questo è ovviamente dove non puoi usare l' CallerMemberNameattributo che è ancora più bello
Assimilater

31

Per aggiungere i miei 2 centesimi, se vuoi aggiornare la tua fonte dati con il nuovo valore del tuo Control, devi chiamare UpdateSource()invece di UpdateTarget():

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

1
Mi piace di più questa risposta.
Chopnut

8

Versione compatibile con MultiBinding ...

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


0

Recuperavo dati dal backend e aggiornavo lo schermo con una sola riga di codice. Ha funzionato. Non sono sicuro del motivo per cui dobbiamo implementare Interface. (Windows 10, UWP)

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

This.Bindings.update () aggiorna tutte le associazioni nella schermata. FYI
Itzdsp

Ho provato this.Bindings.Update () in un usercontrol in UWP e non esiste.
James Esh,

Sì. E questo. Le associazioni ancora non esistono.
James Esh

2
Bindings.Update () è disponibile solo quando vengono utilizzati i binding compilati (x: Bind) ... e i binding compilati sono disponibili solo in UWP
Marian Dolinský

Si prega di dare un'occhiata al commento @ MarianDolinský. Sembra che tu debba eseguire il binding da
xaml
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.