当我们在开发自定义的组件的时候,有没有遇到过这种场景,我们明明没有给FrameworkElement.DataContext
属性赋null
值,为什么他变成null
了?
出现这种问题,可能有以下几种场景:
- 调试的对象不是同一个对象
- 异步代码出现不按常规顺序赋值
- 数据绑定,更改了其数值
- 数据模版或者样式应用,导致数据被重置
前面几种很好理解,调试的过程中也比较容易发现。这次就简单的来说下第四种场景。
先来看个堆栈:
从堆栈信息里面,我们可以发现,MeasureCore
里面调用了ApplyTemplate
的代码。
这个是ContentPresenter
的部分源代码:
private void EnsureTemplate()
{
DataTemplate oldTemplate = Template;
DataTemplate newTemplate = null;
for (_templateIsCurrent = false; !_templateIsCurrent; )
{
_templateIsCurrent = true;
newTemplate = ChooseTemplate();
if (oldTemplate != newTemplate)
{
Template = null;
}
if (newTemplate != UIElementContentTemplate)
{
this.DataContext = Content;
}
else
{
this.ClearValue(DataContextProperty);
}
}
Template = newTemplate;
if (oldTemplate == newTemplate)
{
StyleHelper.DoTemplateInvalidations(this, oldTemplate);
}
}
在首次应用模版的时候,DataContext会被重新赋值。所以就会出现不符合预期的现象。
解决这个问题的办法也很简单,就是在FrameworkElement.ApplyTemplate后,再给DataContext赋值就可以了。
本文会经常更新,请阅读原文: https://huchengv5.gitee.io//post/WPF-DataContext%E8%8E%AB%E5%90%8D%E8%A2%AB%E9%87%8D%E7%BD%AE%E4%B8%BAnull.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名胡承(包含链接: https://huchengv5.gitee.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。