C# PropertyChanged 事件始终为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1512627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 18:18:51  来源:igfitidea点击:

PropertyChanged event always null

c#.netwpfbindinginotifypropertychanged

提问by Dave

I have the following (abbreviated) xaml:

我有以下(缩写)xaml:

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

I have a singleton class:

我有一个单例类:

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

And in my main window constructor:

在我的主窗口构造函数中:

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

I cannot get the textblock to display the test message. When I monitor the code through debug, the PropertyChanged is always null. Any ideas?

我无法让文本块显示测试消息。当我通过调试监视代码时,PropertyChanged 始终为空。有任何想法吗?

回答by kiwipom

Your OnPropertyChanged string must exactly match the name of the property as it's case sensitive.

您的 OnPropertyChanged 字符串必须与属性名称完全匹配,因为它区分大小写。

Try changing

尝试改变

OnPropertyChanged("StatusMsg");

to

OnPropertyChanged("statusMsg");

Update:Also - just noticed that you're binding to StatusMsg (capital 'S'); so the control was not binding to the property, which is another reason why it wasn't updating!

更新:另外 - 刚刚注意到你绑定到 StatusMsg(大写“S”);所以控件没有绑定到属性,这是它没有更新的另一个原因!

回答by Dave

Thanks Jerome! Once I set the DataContext it started working as it should! I added the following to the main window constructor for testing purposes:

谢谢杰罗姆!一旦我设置了 DataContext,它就开始正常工作了!为了测试目的,我将以下内容添加到主窗口构造函数中:

 this.DataContext = testMessage;

回答by Scott Nimrod

There is a couple of items to check for when observing the PropertyChanged event object as null.

将 PropertyChanged 事件对象观察为 null 时,需要检查几个项目。

  1. Ensure the property name passed in as an argument when raising the event actually matches the name of the property you are targeting.

  2. Ensure that you are using only one instance of the object that contains the property you are binding to.

  1. 确保在引发事件时作为参数传入的属性名称实际上与您要定位的属性名称匹配。

  2. 确保您只使用包含要绑定到的属性的对象的一个​​实例。

For item number two, this can be done by simply placing a break point on the class constructor for the object that harbors the property that is being bound. If the breakpoint is triggered more than once, then you have a problem and need to resolve the number of instances of objects to only one instance that your runtime invokes via XAML.

对于第二项,这可以通过简单地在包含被绑定属性的对象的类构造函数上放置一个断点来完成。如果断点被多次触发,那么您就会遇到问题,需要将对象实例的数量解析为您的运行时通过 XAML 调用的仅一个实例。

Thus, it's better to implement that class as a singleton pattern so that you can ensure just one instance of the object at runt-time.

因此,最好将该类实现为单例模式,以便您可以确保在运行时只有一个对象实例。

回答by jadusty

If you follow all instructions, verifying your property name is correct, that it is correctly being assigned a new value, you are using a singleton to guarantee one instance of you view model, and you have successfully assigned your DataContext in the UI - make sure that whatever is forcing your property to update is done after the visual tree has been completed, i.e. move the refresh of your property to a button, rather than say the Loaded event of your window. I say this because I had the same issue, and found that when I refreshed my view model data property from my Infragistics NetAdvantage ribbon window's Loaded event, my PropertyChanged event was always null.

如果您按照所有说明进行操作,验证您的属性名称是否正确,是否正确为其分配了新值,您正在使用单例来保证您的视图模型的一个实例,并且您已在 UI 中成功分配了您的 DataContext - 确保在可视化树完成后,强制您的属性更新的任何内容都已完成,即将您的属性的刷新移动到按钮,而不是说窗口的 Loaded 事件。我这样说是因为我遇到了同样的问题,并且发现当我从 Infragistics NetAdvantage 功能区窗口的 Loaded 事件刷新我的视图模型数据属性时,我的 PropertyChanged 事件始终为空。

回答by danielpops

I ran into this today and wasted some time on it, and eventually figured it out. I hope this helps save you and others some time.

我今天遇到了这个问题,浪费了一些时间,最终弄明白了。我希望这有助于为您和其他人节省一些时间。

If there are no subscribers to your event, and you simply declared the events as:

如果您的事件没有订阅者,并且您只是将事件声明为:

public event EventHandler SomeEventHappened;

Then null reference is expected. The way around this is to declare as follows:

然后预期为空引用。解决这个问题的方法是声明如下:

public event EventHandler SomeEventHappened = delegate { };

This will ensure that it is not a null reference when you call as

这将确保当您调用时它不是空引用

SomeEventHappened()

Another pattern i've seen is to notinitialize to delegate {} and instead check for null:

我见过的另一种模式是初始化为委托 {} 而是检查 null:

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

回答by vancutterromney

Another point - for PropertyChanged to be null make sure you bind the object to the DataContext and then set the Path instead of directly assigning the property to the UI field.

另一点 - 要使 PropertyChanged 为 null,请确保将对象绑定到 DataContext,然后设置 Path 而不是直接将属性分配给 UI 字段。

回答by lukaszk

Just in case: I had a similar problem but my mistake was that class which implemented INotifyPropertyChanged was private. Making it public resolved my case.

以防万一:我有一个类似的问题,但我的错误是实现 INotifyPropertyChanged 的​​类是私有的。公开解决了我的案子。

回答by OutThere

I also have seen the PropertyChanged event be null when I have existing data assigned to the control's data bound property:

当我将现有数据分配给控件的数据绑定属性时,我还看到 PropertyChanged 事件为 null:

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

Where as this works:

这在哪里工作:

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

回答by saha0404

in my case this make it to work:

在我的情况下,这使它起作用:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;    // this row fixed everything
    }
    ****
    Some code here with properties etc
    ***
}

回答by DGR

I had a similar issue, neither solutions above helped me. All I needed to do was to use the built c# Propertychanged. Beforehand I have implemented propertyChanged (by an accident) and it pointed at nothing.

我有一个类似的问题,上面的解决方案都没有帮助我。所有我需要做的是使用内置的C#Propertychanged。事先我已经实现了 propertyChanged(偶然)并且它没有指向任何东西。