2009-10-03 4 views
33

У меня есть следующий (сокращенный) XAML:PropertyChanged события всегда нуль

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

У меня есть класс одноплодный:

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

И в моем главном окне конструктора:

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

Я не могу заставить текстовый блок отображать тестовое сообщение. Когда я отслеживаю код с помощью отладки, свойство PropertyChanged всегда равно нулю. Есть идеи?

+19

Где вы установили свой DataContext с экземпляром StatusMessage? –

ответ

9

Ваша строка OnPropertyChanged должна точно соответствовать имени свойства, так как оно чувствительно к регистру.

Попробуйте изменить

OnPropertyChanged("StatusMsg"); 

в

OnPropertyChanged("statusMsg"); 

Update: Также - только заметил, что вы привязки к StatusMsg (капитал 'S'); поэтому элемент управления не был привязан к свойству, что является еще одной причиной, по которой она не обновлялась!

+0

Я сделал 2 изменения, так как вы предложили Ian, свойство PropertyChanged по-прежнему оценивается как NULL. Как ни странно, я знаю, что это должно сработать! Я отредактировал код, чтобы отразить изменения. – Dave

+2

@IanR я не думаю, что это будет null, из-за этого он просто не обновил бы свойство , он заявляет, что он даже не получил возможность обновлять, так как он равен нулю –

17

Thanks Jerome! Как только я установил DataContext, он начал работать так, как должен! Я добавил следующее в главном окне конструктора для тестирования:

this.DataContext = testMessage; 
0

Существует несколько пунктов, чтобы проверить при наблюдении объекта события PropertyChanged как нуль.

  1. Убедиться, что имя свойства, переданное в качестве аргумента при поднятии события, фактически соответствует имени объекта, на который вы нацеливаетесь.

  2. Убедитесь, что вы используете только один экземпляр объекта, который содержит свойство, к которому вы привязываетесь.

По пункту номер два, это может быть сделано, просто помещая точку останова на конструктор класса для объекта, который таит в себе свойство, связывался. Если точка останова запускается более одного раза, возникает проблема, и вам необходимо разрешить количество экземпляров объектов только для одного экземпляра, который ваша среда выполнения вызывает через XAML.

Таким образом, лучше реализовать этот класс как одноэлементный шаблон, чтобы вы могли обеспечить только один экземпляр объекта во время выполнения.

+3

Что, Singleton? Какие?! Никогда не читал столько мусора в моей жизни. Система привязки будет подписана на событие правильного экземпляра. Если бы WPF просто не работал. Проконсультируйтесь с любой новеевой статьей MVVM, чтобы продемонстрировать, насколько вы ошибаетесь. – Gusdor

+0

Это говорит по собственному опыту от проблем. У меня было несколько экземпляров моей модели представления во время выполнения. Таким образом, это обновление работало для меня. Спасибо за ваш вклад. –

+0

Кроме того, убедитесь, что загружены все данные (т. Е. Загруженное событие). –

-2

Если вы следуете всем инструкциям, проверка правильности вашего имени свойства, то для правильного назначения нового значения вы используете одноэлементный режим, чтобы гарантировать, что один экземпляр модели вы просматриваете, и вы успешно присвоили свой DataContext в UI - убедитесь, что все, что заставляет ваше свойство обновляться, выполняется после того, как визуальное дерево завершено, т.е. переместите обновление вашего свойства на кнопку, вместо того, чтобы сказать событие Loaded вашего окна. Я говорю об этом, потому что у меня была такая же проблема, и обнаружил, что когда я обновил свойство данных модели просмотра из моего загруженного события в ленточном окне Infragistics NetAdvantage, мое событие PropertyChanged всегда было нулевым.

+0

Этот ответ имеет ужасную грамматику и не дает структурированного ответа. Вы предлагаете, чтобы человек наблюдал за загрузкой просмотра, что является сложным и, скорее всего, еще более запутывает их. Если это действительно ваш метод устранения неполадки обработчика события null Prop, вы должны предоставить методологию, а не пример того, как вы это делаете. –

14

Я столкнулся с этим сегодня и потратил немного времени на это, и в итоге понял это. Надеюсь, это поможет вам и другим.

Если нет подписчиков на ваше мероприятие, и вы просто объявили события, как:

public event EventHandler SomeEventHappened; 

Тогда нулевая ссылка ожидается. Обойти это объявить следующим образом:

public event EventHandler SomeEventHappened = delegate { }; 

Это будет гарантировать, что это не пустая ссылка, если вы звоните в

SomeEventHappened() 

Другой образец я видел это не инициализации делегировать {} и вместо того, чтобы проверить нуль:

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

Причина, по которой параметр 'this.DataContext = testMessage ;' заставляет его работать, заключается в том, что в моем ответе, который эффективно устанавливает подписку на событие, которое вы хотите запустить, следовательно, оно больше не является нулевым. – danielpops

+1

Я считаю, что подход «проверка на нуль» теперь является предпочтительным. Я попытался инициализировать обработчик событий, как это было в вашем первом случае, и, правда, событие больше не было нулевым, но событие INotifyPropertyChanged не вызвало обновление списка , который я использовал. Исправление заключалось в использовании INotifyCollectionChanged (см. Https://stackoverflow.com/questions/37329991/propertychanged-event-handler-always-null-in-win-phone-8-application для моего опыта с этой проблемой). – rfreytag

0

Еще один момент - для PropertyChanged утратившими убедитесь, что вы связать объект с DataContext и т купите Путь вместо прямого назначения свойства полю интерфейса.

3

На всякий случай: У меня была аналогичная проблема, но моя ошибка заключалась в том, что класс, который реализовал INotifyPropertyChanged, был закрытым. Сделать это публично разрешило мое дело.

1

Я также видел событие PropertyChanged быть нулевым, когда я имеющиеся данные назначены данные элемента управления связаны собственности:

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

Где, как это работает:

<TextBlock Name="CarTireStatus" Text="{Binding TireStatus}" ></TextBlock> 
Смежные вопросы