为啥 WPF 将我的数据上下文设置为 MS.Internal.NamedObject?

Posted

技术标签:

【中文标题】为啥 WPF 将我的数据上下文设置为 MS.Internal.NamedObject?【英文标题】:Why is WPF setting my data context to MS.Internal.NamedObject?为什么 WPF 将我的数据上下文设置为 MS.Internal.NamedObject? 【发布时间】:2013-11-07 00:40:25 【问题描述】:

我有一个程序在 .NET 4.0 / Windows 7 上崩溃,但在 .NET 4.5 / Windows 8+ 上运行良好。销毁控件时(例如,通过关闭控件所在的窗口),WPF 似乎试图将 DataContext 设置为 MS.Internal.NamedObject 类型的对象——这失败了,因为控件总是期望数据上下文是与该视图配套的视图模型:

System.InvalidCastException:无法将“MS.Internal.NamedObject”类型的对象转换为“Foo.Bar.BazViewModel”类型。

这里发生了什么?我可以要求 WPF 不要像这样弄乱数据上下文,还是应该在发生这种情况时禁用控件?

【问题讨论】:

Can I ask WPF to not... - 不,你不能强迫 WPF 满足你的意愿。更正您拥有的任何有问题的代码。如果将 UI 元素的 DataContext 设置为任何对象,也不应在任何意外情况下,UI 元素不应使整个应用程序崩溃。更正您的代码。 @HighCore:没有任何地方证明 WPF 保留从控件下方更改 DataContext 的权利。 上下文...您究竟是如何销毁控件 @OmegaMan:用户关闭控件所在的窗口。 @BillyONEal 您可以继续尝试用木刀穿透铁墙(并想知道为什么没有记录任何木头不能破坏铁的地方),或者您可以更正有问题的代码。应该是if (DataContext is MyViewModel) 的问题......事情就是这样。顺便说一句,即使 WPF 没有这样做,您也会在您的应用程序中创建潜在的崩溃,这很糟糕。如果需要,UI 元素应该“期望”特定的 ViewModel,但如果传递了不同的 ViewModel / DataContext,它们永远不会崩溃。 【参考方案1】:

其他事情正在发生。

我建议创建一个独立的示例,该示例能够代表结构、绑定和提炼为最基本形式的数据。如果该问题可以在独立项目中重现,那么您可能有一个应该报告给Microsoft Connect 的错误。

示例项目更有可能揭示导致情况的差异,从而使您能够解决问题。或者至少将其发布到 Stack Overflow 并让答案鲨鱼享用新鲜的示例杀戮;可以这么说。


异步数据操作可能来得太晚了。检查是否有任何可能被关闭的帖子更新。

【讨论】:

我强烈怀疑这是在 .NET 4.5 和/或 Win8 中修复的某种错误。 @BillyONEal 程序是在 4 上编写然后移植到 4.5 还是反之亦然? 正在 Win8 和/或 8.1 机器上进行开发,.NET 4.5,目标平台设置为 .NET 4.0。直到客户尝试在安装了 .NET 4.0(仅)的 Win7 计算机上运行该应用程序后,问题才出现。不管是操作系统还是 .NET 版本,都没有用完。【参考方案2】:

我不确定这是否是同一个问题,但对于它的价值,我还遇到了一个奇怪的问题,WPF 会为ItemsControl 中的每个视图对象调用我的DataContextChanged 处理程序。当我将远程桌面连接到运行应用程序的服务器时,就会发生这种情况——但我无法在我的机器或任何其他机器上重现它。不知何故,我发现了根本原因:当当前的 Windows 7 主题从 Aero 更改为 Classic(或反之亦然)时,ItemsControl 中每个对象的DataContext 将设置为MS.Internal.NamedObject(但不会被破坏) .我通过将配色方案从 Classic 更改为 Basic 暂时回避了这个问题,这防止了在 RDP 登录时发生这种现象。对于我的应用程序正在运行并且用户确实更改了主题的情况,我修改了我的处理程序方法以在 DataContext 不是预期类型时返回。然而,即便如此,现在集合中的所有视图项都有双倍。每次主题更改时,都会创建另一组完整的实例(每个“组”的最新实例具有 WPF 设置的正确数据上下文;其余的都是孤立的)

【讨论】:

以上是关于为啥 WPF 将我的数据上下文设置为 MS.Internal.NamedObject?的主要内容,如果未能解决你的问题,请参考以下文章

通过 Uri 将参数传递给 WPF 页面

为啥我不能将我的系统时间设置为接近夏令时转换的时间

如何将我的 Web 应用程序的上下文根设置为“/”。

wpf中怎么为datagrid绑定一个list 我的代码如下,为啥显示出来的全是空行?。。。 似乎数据个数是对的…

使用 WPF C# 将我的 SQL 数据库导出为 XML

为啥访问我的 Storyboard x:Name 在 Silverlight 中有效,但在 WPF 中无效?