从基于资源的绑定切换为设计时绑定后,基于IDataErrorInfo的验证失效问题
问题分析与解决方案
你遇到的问题核心在于对d:DataContext的作用理解有偏差——这个标记只在设计阶段生效,完全不会影响程序运行时的数据源。
为什么你的两个示例表现不同?
- 第一个示例里,你通过
StackPanel.Resources创建了一个PersonImplementsIDataErrorInfo的实例,并用Source={StaticResource data}指定了绑定的源。这时候运行时绑定有真实的对象可以触发验证逻辑,所以ValidatesOnDataErrors=True能正常工作。 - 第二个示例去掉了StaticResource后,虽然保留了
d:DataContext="{d:DesignInstance ...}",但这个标记只是给Visual Studio/Blend设计器看的:让设计器能显示假数据、预览绑定效果,运行时程序并不会自动创建这个ViewModel的实例。此时你的TextBox绑定的DataContext是null,没有真实的对象去调用IDataErrorInfo的验证方法,自然就看不到验证效果了。
为什么你的代码库能正常工作?
你维护的代码库肯定在运行时通过其他方式设置了真实的DataContext,只是你没注意到:
- 可能在View的后台代码(比如
TheView.xaml.cs)的构造函数里,写了DataContext = new TheViewModel();; - 或者用了依赖注入框架(比如Prism、Autofac)自动注入ViewModel;
- 也可能用了ViewModelLocator之类的模式,通过XAML标记扩展自动绑定ViewModel。
而d:DataContext只是代码库用来优化设计体验的辅助标记,和运行时的验证逻辑完全无关。
修复你的示例的方法
要让第二个示例的验证生效,只需要在MainWindow.xaml.cs里手动设置运行时的DataContext即可:
public MainWindow() { InitializeComponent(); // 添加这一行,给运行时提供真实的ViewModel实例 DataContext = new PersonImplementsIDataErrorInfo(); }
这样既保留了设计时的d:DataContext让设计器预览,运行时也有了真实的数据源,ValidatesOnDataErrors=True就能触发IDataErrorInfo的验证逻辑了。
内容的提问来源于stack exchange,提问作者user32882
相关产品推荐
相关产品推荐

