Событие PropertyChanged всегда пустое - PullRequest
34 голосов
/ 03 октября 2009

У меня есть следующее (сокращенно) xaml:

<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 всегда имеет значение null. Есть идеи?

Ответы [ 9 ]

18 голосов
/ 03 октября 2009

Спасибо, Джером! Как только я установил DataContext, он начал работать как надо! Для целей тестирования я добавил следующее в конструктор главного окна:

 this.DataContext = testMessage;
14 голосов
/ 31 марта 2011

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

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

public event EventHandler SomeEventHappened;

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

public event EventHandler SomeEventHappened = delegate { };

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

SomeEventHappened()

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

var eventToRaise = SomeEventHappened;
if( eventToRaise != null )
{
    SomeEventHappened()
}
9 голосов
/ 03 октября 2009

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

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

OnPropertyChanged("StatusMsg");

до

OnPropertyChanged("statusMsg");

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

4 голосов
/ 05 декабря 2013

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

1 голос
/ 15 февраля 2015

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

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

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

<TextBlock Name="CarTireStatus" Text="{Binding TireStatus}" ></TextBlock>
1 голос
/ 16 октября 2013

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

0 голосов
/ 01 апреля 2019

в моем случае это работает:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;    // this row fixed everything
    }
    ****
    Some code here with properties etc
    ***
}
0 голосов
/ 26 января 2011

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

0 голосов
/ 15 ноября 2010

Есть пара элементов, которые нужно проверить, наблюдая объект события PropertyChanged как ноль.

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

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

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

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

...