Подтвердить что ты не робот

Событие PropertyChanged всегда равно нулю

У меня есть следующий (сокращенный) 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 всегда равно нулю. Любые идеи?

4b9b3361

Ответ 1

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

 this.DataContext = testMessage;

Ответ 2

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

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

public event EventHandler SomeEventHappened;

Тогда ожидается нулевая ссылка. Способ вокруг этого состоит в том, чтобы объявить следующее:

public event EventHandler SomeEventHappened = delegate { };

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

SomeEventHappened()

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

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

Ответ 3

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

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

OnPropertyChanged("StatusMsg");

к

OnPropertyChanged("StatusMsg");

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

Ответ 4

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

Ответ 5

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

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

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

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

Ответ 6

Существует пара элементов для проверки при наблюдении объекта события PropertyChanged как null.

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

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

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

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

Ответ 7

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

Ответ 8

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