2009-10-03 19 views
33

Tengo el siguiente XAML (abreviado):caso PropertyChanged siempre nula

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

tengo una clase 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"); 
     } 
    } 
} 

Y en mi ventana principal constructor:

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

No puedo hacer que el bloque de texto muestre el mensaje de prueba. Cuando controlo el código a través de la depuración, PropertyChanged siempre es nulo. ¿Algunas ideas?

+19

¿Dónde se establece su DataContext con una instancia de StatusMessage? –

Respuesta

9

Su cadena OnPropertyChanged debe coincidir exactamente con el nombre de la propiedad, ya que distingue entre mayúsculas y minúsculas.

Intenta cambiar

OnPropertyChanged("StatusMsg"); 

a

OnPropertyChanged("statusMsg"); 

Actualización: También - acabo de dar cuenta de que estás unión a statusMsg (capital 'S'); por lo que el control no era vinculante para la propiedad, ¡que es otra razón por la cual no estaba actualizando!

+0

Hice los 2 cambios como sugirió Ian, PropertyChanged todavía está evaluando como NULL. ¡Un poco extraño, sé que esto debería funcionar! Edité el código para reflejar los cambios. – Dave

+2

@IanR no creo que sea nulo, por eso, simplemente no actualiza la propiedad afirma que ni siquiera tiene la oportunidad de actualizar ya que es nulo –

17

Gracias Jerome! Una vez que configuré DataContext, ¡comenzó a funcionar como debería! He añadido lo siguiente al constructor de la ventana principal para propósitos de prueba:

this.DataContext = testMessage; 
0

Hay un par de artículos para comprobar al observar el objeto de evento PropertyChanged como nulo.

  1. Asegúrese de que el nombre de la propiedad en el pasado como argumento al levantar el evento en realidad coincide con el nombre de la propiedad que está apuntando.

  2. Asegúrese de estar utilizando solo una instancia del objeto que contiene la propiedad a la que se está vinculando.

Para el artículo número dos, esto se puede hacer simplemente colocando un punto de interrupción en el constructor de clase para el objeto que alberga la propiedad que está siendo atado. Si el punto de interrupción se activa más de una vez, entonces tiene un problema y necesita resolver el número de instancias de objetos en una sola instancia que invoca su tiempo de ejecución a través de XAML.

Por lo tanto, es mejor implementar esa clase como un patrón singleton para que pueda garantizar solo una instancia del objeto en tiempo de ejecución.

+3

¿Qué, Singleton? ¡¿Qué?! Nunca leas tanta basura en mi vida. El sistema de enlace se suscribirá al evento de la instancia correcta. Si no, WPF simplemente no funcionaría. Consulte cualquier artículo MVVM para principiantes para una demostración de mejores prácticas de lo equivocado que está. – Gusdor

+0

Esto está hablando desde mi propia experiencia de resolución de problemas. Tuve más de una instancia de mi modelo de vista en tiempo de ejecución. Por lo tanto, esta actualización funcionó para mí. Gracias por tu aporte. –

+0

Además, asegúrese de que todos los datos estén cargados (es decir, evento Cargado). –

-2

Si sigue todas las instrucciones, verifica que el nombre de su propiedad es correcto, que se le está asignando un nuevo valor, está utilizando un singleton para garantizar una instancia de su modelo y ha asignado con éxito su DataContext en el Interfaz de usuario: asegúrese de que todo lo que obligue a su propiedad a actualizar se realice después de que se haya completado el árbol visual, es decir, mueva la actualización de su propiedad a un botón, en lugar de decir el evento Cargado de su ventana. Digo esto porque tuve el mismo problema y descubrí que cuando actualicé la propiedad de datos de mi modelo de vista desde el evento Loaded de mi ventana de cinta Infragistics NetAdvantage, mi evento PropertyChanged siempre fue nulo.

+0

Esta respuesta tiene una gramática terrible y no ofrece una respuesta estructurada. Está proponiendo que la persona monitoree desde la vista de carga, lo cual es complejo y probablemente los confundirá aún más. Si este es realmente su método de solución de problemas de un controlador de eventos Prop nulo, debe proporcionar la metodología, no un ejemplo de lo que está haciendo. –

14

Me encontré con esto hoy y perdí un poco de tiempo en él, y finalmente lo descubrí. Espero que esto ayude a salvarte a ti y a los demás en algún momento.

Si no hay suscriptores a su caso, y simplemente declararon los eventos como: Se espera que

public event EventHandler SomeEventHappened; 

referencia un valor nulo. La forma de evitar esto es declarar como sigue:

public event EventHandler SomeEventHappened = delegate { }; 

Esto asegurará que no es una referencia nula cuando se llama como

SomeEventHappened() 

Otro patrón que he visto es que no initialize delegar {} y en lugar de comprobar la nula:

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

La razón por la que establecer 'this.DataContext = testMessage;' hace que funcione es que por mi respuesta, que establece eficazmente una suscripción el evento que desea disparar, por lo tanto, ya no es nulo. – danielpops

+1

Creo que el enfoque preferido es el enfoque de "verificar nulo". Intenté inicializar el controlador de eventos como lo hizo en su primer caso y, es cierto, el evento ya no era nulo pero el evento INotifyPropertyChanged no activó una actualización de la Lista que estaba usando. La solución fue utilizar INotifyCollectionChanged (ver: https://stackoverflow.com/questions/37329991/propertychanged-event-handler-always-null-in-win-phone-8-application por mi experiencia con este problema). – rfreytag

0

Otro punto - para PropertyChanged sea nula asegúrese de enlazar el objeto a la DataContext yt Establece la ruta en lugar de asignar directamente la propiedad al campo UI.

3

Por las dudas: Tuve un problema similar pero mi error fue que la clase que implementó INotifyPropertyChanged era privada. Hacerlo público resolvió mi caso.

1

También he visto el evento PropertyChanged ser nula cuando haya datos existentes asignado a los datos del control de las propiedades compartidas:

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

Cuando este tipo de obras:

<TextBlock Name="CarTireStatus" Text="{Binding TireStatus}" ></TextBlock> 
Cuestiones relacionadas