这是一个非常简单的问题,但我想知道是否有人可以解释第4行实际上在做什么?所以第一行给处理程序一个事件。我真的不知道在什么情况下处理程序将返回null或最后一行的内容。
当你传递处理程序你的对象和哪个属性发生了变化时,它对它们有什么影响?
PropertyChangedEventHandler handler = PropertyChanged; //property changed is the event
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
我认为我用这个来获取code,但我想了解它在做什么。
答案 0 :(得分:36)
如果你刚刚做了:
PropertyChanged(this, new PropertyChangedEventArgs(name))
如果没有人订阅活动NullReferenceException
,您将获得PropertyChanged
。要抵消这种情况,请添加空检查:
if(PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name))
}
现在,如果您使用多线程,则可以取消订阅空检查和事件调用,因此您仍然可以获得NullReferenceException
。为了处理这个问题,我们将事件处理程序复制到临时变量
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
现在如果有人取消订阅该事件,我们的临时变量handler
仍将指向旧函数,此代码现在无法抛出NullReferenceException
。
大多数情况下,您会看到人们使用关键字var
,这使得您无需输入完整类型的临时变量,这是您在代码中最常见到的表单
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
答案 1 :(得分:8)
PropertyChanged
是根据界面中的定义声明的事件:
public event PropertyChangedEventHandler PropertyChanged;
像这样定义的Events实际上是事件处理程序列表的语法糖,您可以通过订阅或通过取消订阅删除委托来添加委托(即对函数的引用)。 / p>
现在,当您调用一个事件,即PropertyChanged(...)
时,内部发生的事情是该内部列表中的每个代理都会使用这些参数单独调用。这将告诉您事件的所有订阅者事件发生。
现在,handler
变量的全部原因是PropertyChanged
可以为空。如果没有订阅它,那么调用事件(或者更确切地说是事件处理程序列表)将不起作用,因此这只是确保您可以实际执行处理程序的一种方法。
答案 2 :(得分:6)
handler
可以为null,第四行引发给定属性名称的事件(执行所有已订阅的处理程序)。
通常,当您使用绑定时,WPF框架将订阅PropertyChanged
,因此一旦绑定属性发生更改,它就可以更新绑定。