为什么WPF会吞噬数据绑定异常?

20

我正在学习WPF,但困惑的是数据绑定异常不会引起运行时/未处理异常。

有人能解释一下数据绑定以这种方式工作的好处吗?我认为肯定有好处,但目前还没有看到(免责声明:我刚开始学习数据绑定)。

如果有解释此决策理论或实际原因的资源链接也可以。


1
重复问题:https://dev59.com/iXNA5IYBdhLWcg3wZ85S - Kent Boogaart
1
不是重复问题。这个问题是关于为什么,而链接的问题是关于如何处理它。 - Phil Sandler
链接问题的第一个答案解释了如何处理它。自定义跟踪源 ftw。 - Kent Boogaart
1
肯特:我认为你误读了菲尔的评论。这个问题是关于“为什么”,而不是“该怎么做”。其他问题的答案并不能回答菲尔的问题。 - itowlson
1
Kent:请重新阅读我的问题和链接的问题。这完全不是重复的。我不是在问该怎么做,我在问为什么它会那样工作。 - Phil Sandler
4个回答

9
我不确定,但我怀疑这是因为没有处理异常的地方。
假设您有一些属性要绑定,但有时该属性为空。 (例如,{Binding Name.Length},其中Name是可能为null的字符串属性。)在这种情况下,您希望此操作无效,因为您知道当Name为null时,控件将永远不会显示(由于触发器等原因),或者因为您知道这将是绑定源正在加载其数据时的短暂条件。
现在假设WPF在尝试调用空Name字符串上的Length时传播了NullReferenceException。在过程代码中,您会捕获并吞噬此异常,因为您知道它是良性的。但是您无法在WPF绑定代码周围放置异常处理程序。它从WPF深处的某个地方调用。因此,异常将一直上升到Application.Run,这不是一个非常有用的位置来捕获它。
因此,我认为WPF的开发人员决定自己吞噬异常,而不是让您将绑定异常处理程序集中在Application.Run中。只是一个理论...

2
我不确定我同意这个观点。从技术上讲,Binding 元素只有一个字符串路径,稍后会转换为 PropertyPath 实例。然后,将使用此实例向上导航到目标属性。因此,这个导航器可能会在每一步检查 null 并在遇到它时返回它;但仍有问题的是,它如何处理被访问的属性 getter 抛出的实际异常。在我看来,那是一场灾难的配方。 - Crono

5

我认为这是因为生成异常的成本太高了。当前的实现即使在存在一些无效绑定的情况下也能正常工作,而以当前的形式,这实际上会对性能产生非常显著的影响。举个例子,创建一个进行绑定并将1,000条记录加载到其中的DataGrid。测量所有绑定正确的性能,然后再测量其中一个绑定错误的性能。差异是相当大的。如果还要加上异常类实例,情况可能会变得糟糕得不可控。这只是我的意见。


有趣的想法!我没有考虑到在列表控件的每个项目中捕获和处理异常的性能问题... - itowlson
啊,我想点赞这个帖子,但我不小心“取消”了点赞,现在我无法重新点击它来恢复我的点赞。抱歉,Keith--虚拟+1! - itowlson
绑定错误的绑定会很慢,因为在Visual Studio的输出窗口中显示警告消息;输出窗口非常缓慢。 - Catalin DICU
起初我也是这么想的,但当没有附加调试器时,在生产代码中确实存在差异。 - keithwarren7

4
我不知道为什么这是默认行为,但有办法避免这种情况。例如,即使它不会告诉你绑定错误的原因,输出窗口会显示。您也可以使用绑定验证来捕获它。编辑:我找到了一篇文章,提出了一个非常好的想法,创建测试用例来捕获那些讨厌的静默绑定错误(我喜欢文章顶部的照片)。请参考此文章

实际上,您可以在运行时的输出窗口中看到绑定异常。您知道在设计时(即在 Blend 中)是否也可以了解发生的异常吗? - Benoit Blanchon
链接已失效。 - Neil

0

这里是一个博客文章的链接,作者在文章中讲述了一个案例,认为绑定错误保持沉默是有意义的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接