2009-10-03 30 views
33

Ho il seguente (abbreviato) XAML:evento PropertyChanged sempre nullo

<TextBlock Text="{Binding Path=statusMsg, UpdateSourceTrigger=PropertyChanged}"/> 

Ho una classe Singleton:

public class StatusMessage : INotifyPropertyChanged 
{ 
    private static StatusMessage instance = new StatusMessage(); 

    private StatusMessage() { } 

    public static StatusMessage GetInstance() 
    { 
     return instance; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(string status) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(status)); 
     } 
    } 

    private string statusMessage; 
    public string statusMsg 
    { 
     get 
     { 
      return statusMessage; 
     } 
     set 
     { 
      statusMessage = value; 
      OnPropertyChanged("statusMsg"); 
     } 
    } 
} 

E nella mia finestra principale costruttore:

StatusMessage testMessage = StatusMessage.GetInstance(); 
testMessage.statusMsg = "This is a test msg";  

Non riesco a ottenere il blocco testo per visualizzare il messaggio di prova. Quando controllo il codice tramite debug, PropertyChanged è sempre nullo. Qualche idea?

+19

Dove si fa a impostare il vostro DataContext con un'istanza StatusMessage? –

risposta

9

La stringa OnPropertyChanged deve corrispondere esattamente al nome della proprietà in quanto è sensibile alla distinzione tra maiuscole e minuscole.

Prova cambiando

OnPropertyChanged("StatusMsg"); 

a

OnPropertyChanged("statusMsg"); 

Aggiornamento: anche - appena notato che sei legame StatusMsg (capitale 'S'); quindi il controllo non era vincolante per la proprietà, che è un altro motivo per cui non si stava aggiornando!

+0

Ho apportato le 2 modifiche come suggerito Ian, PropertyChanged sta ancora valutando come NULL. Un po 'strano, so che questo dovrebbe funzionare! Ho modificato il codice per riflettere le modifiche. – Dave

+2

@IanR non penso che sarebbe nulla, per questo, , semplicemente non aggiornerebbe la proprietà afferma che non ha nemmeno la possibilità di aggiornare dato che è null –

17

Grazie Jerome! Una volta impostato DataContext, ha iniziato a funzionare come dovrebbe! Ho aggiunto il seguente alla finestra principale costruttore a scopo di test:

this.DataContext = testMessage; 
0

C'è un paio di elementi per verificare quando si osserva l'oggetto evento PropertyChanged come null.

  1. Verificare che il nome della proprietà sia passato come argomento quando l'evento di aumento corrisponde effettivamente al nome della proprietà di destinazione.

  2. Assicurarsi di utilizzare solo un'istanza dell'oggetto che contiene la proprietà a cui si sta vincolando.

Per la voce numero due, questo può essere fatto semplicemente mettendo un punto di interruzione sul costruttore della classe per l'oggetto che ospita la proprietà che viene legato. Se il punto di interruzione viene attivato più volte, si verifica un problema e occorre risolvere il numero di istanze di oggetti in una sola istanza richiamata dal runtime tramite XAML.

Pertanto, è meglio implementare quella classe come un modello singleton in modo da poter garantire una sola istanza dell'oggetto a tempo runt.

+3

Cosa, Singleton? Che cosa?! Non ho mai letto così tanta spazzatura nella mia vita. Il sistema di associazione si iscriverà all'evento dell'istanza corretta. Se non WPF non avrebbe funzionato. Consulta qualsiasi articolo MVVM per principianti per una dimostrazione pratica e pratica di quanto sei sbagliato. – Gusdor

+0

Questo sta parlando dalla mia esperienza di trouble-shooting. Ho avuto più di una istanza del mio modello di visualizzazione in fase di esecuzione. Pertanto, questo aggiornamento ha funzionato per me. Grazie per la tua indicazione, comunque. –

+0

Inoltre, assicurarsi che tutti i dati siano caricati (ad esempio evento caricato). –

-2

Se si seguono tutte le istruzioni, verificando il nome della proprietà è corretto, che viene assegnato correttamente un nuovo valore, si sta utilizzando un singleton per garantire un'istanza del proprio modello di visualizzazione e si è assegnato correttamente il DataContext nel UI: assicurati che qualsiasi cosa stia costringendo la tua proprietà ad aggiornare sia fatta dopo che l'albero visivo è stato completato, cioè sposta l'aggiornamento della tua proprietà su un pulsante, invece di dire l'evento Loaded della tua finestra. Dico questo perché ho avuto lo stesso problema, e ho scoperto che quando ho aggiornato la proprietà dei miei dati del modello di visualizzazione dall'evento Loaded della mia finestra nastro Infragistics NetAdvantage, il mio evento PropertyChanged era sempre nullo.

+0

Questa risposta ha una grammatica terribile e non offre una risposta strutturata. Stai proponendo che il monitor della persona dal caricamento della vista, che è complesso e probabilmente li confonderà ancora di più. Se questo è davvero il tuo metodo di risoluzione dei problemi di un gestore di eventi Prop nullo, dovresti fornire la metodologia e non un esempio di come lo fai tu. –

14

Mi sono imbattuto in questo oggi e ho perso un po 'di tempo su di esso, e alla fine l'ho capito. Spero che questo aiuti a salvare te e gli altri un po 'di tempo.

Se non ci sono abbonati al vostro evento, e semplicemente dichiarato gli eventi come: si prevede

public event EventHandler SomeEventHappened; 

riferimento Poi nulla. Il modo per aggirare questo è quello di dichiarare come segue:

public event EventHandler SomeEventHappened = delegate { }; 

Questo farà sì che non è un riferimento null quando si chiama come

SomeEventHappened() 

Un altro modello che ho visto è quello di non inizializzazione di delegare {} e invece verificare la presenza di null:

var eventToRaise = SomeEventHappened; 
if(eventToRaise != null) 
{ 
    SomeEventHappened() 
} 
+1

Il motivo per cui l'impostazione 'this.DataContext = testMessage;' lo fa funzionare è che per la mia risposta, che stabilisce in modo efficace un abbonamento all'evento che si desidera licenziare, quindi non è più nullo. – danielpops

+1

Credo che l'approccio "check for null" sia ora l'approccio preferito. Ho provato a inizializzare il gestore di eventi come hai fatto nel tuo primo caso e, vero, l'evento non era più nullo ma l'evento INotifyPropertyChanged non ha attivato un aggiornamento alla lista che stavo usando. La soluzione era usare INotifyCollectionChanged (si veda: https://stackoverflow.com/questions/37329991/propertychanged-event-handler-always-null-in-win-phone-8-application per la mia esperienza con questo problema). – rfreytag

0

Un altro punto - per PropertyChanged per essere nullo assicurarsi che si associa l'oggetto per il DataContext e t gallina imposta il percorso invece di assegnare direttamente la proprietà al campo dell'interfaccia utente.

3

Nel caso in cui: Avevo un problema simile ma il mio errore era che la classe che implementava INotifyPropertyChanged era privata. Rendendolo pubblico ha risolto il mio caso.

1

Ho anche visto l'evento PropertyChanged essere nullo quando avrò i dati esistenti assegnato ai dati del controllo di proprietà vincolati:

<TextBlock Name="CarTireStatus" Text="{Binding TireStatus}" >Bad Text!</TextBlock> 

Dove come funziona:

<TextBlock Name="CarTireStatus" Text="{Binding TireStatus}" ></TextBlock> 
Problemi correlati