WPF中ValidatesOnDataErrors与NotifyOnValidationError失效求助
这个问题我之前也碰到过!核心原因是你的TaskManagerViewModel没有实现WPF验证机制所需的接口,导致TextBox无法识别到验证错误状态,所以只弹出了提示但控件本身没变红。
问题分析
你的模型Task虽然加了[Required]特性,但WPF的验证系统是通过视图模型来传递错误信息给视图控件的。当前你的VM只是简单封装了模型的Name属性,没有实现IDataErrorInfo或INotifyDataErrorInfo接口——这两个接口是WPF用来获取验证错误、更新控件状态的关键。
解决方案:让VM实现IDataErrorInfo接口
IDataErrorInfo是WPF中用于简单验证场景的标准接口,我们可以通过它来复用模型上的DataAnnotations验证规则。
1. 修改ViewModel代码
更新你的TaskManagerViewModel,实现IDataErrorInfo接口,并在索引器中验证Name属性:
using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Collections.Generic; public class TaskManagerViewModel : ViewModelBase, ITaskManagerViewModel, IDataErrorInfo { public Task CurrentTask => taskManager.CurrentTask; public string Name { get { return CurrentTask.Name; } set { CurrentTask.Name = value; IsDirty = true; RaisePropertyChanged(); // 触发验证状态更新 RaisePropertyChanged(nameof(Name)); } } // IDataErrorInfo 接口实现 public string Error => string.Empty; public string this[string columnName] { get { if (columnName == nameof(Name)) { var validationContext = new ValidationContext(CurrentTask) { MemberName = nameof(Task.Name) }; var validationResults = new List<ValidationResult>(); Validator.TryValidateProperty(CurrentTask.Name, validationContext, validationResults); if (validationResults.Any()) { return validationResults.First().ErrorMessage; } } return null; } } }
2. 确认视图Binding的设置
你已经在TextBox的Binding里加了ValidatesOnDataErrors=True和NotifyOnValidationError=True,这部分是对的,不需要修改:
<TextBox Grid.Row="0" Grid.Column="3" Name="Name" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" />
3. 检查控件样式(可选)
如果做完上面两步还是没变红,可能是你的TextBox用了自定义样式,覆盖了默认的错误状态样式。可以添加一个基础样式来确保错误状态显示红色边框:
<Style TargetType="TextBox"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="BorderBrush" Value="Red"/> <Setter Property="BorderThickness" Value="2"/> </Trigger> </Style.Triggers> </Style>
为什么这样有效?
当你在TextBox中输入内容时,UpdateSourceTrigger=PropertyChanged会实时更新VM的Name属性,WPF会通过IDataErrorInfo的索引器获取该属性的验证错误,然后自动设置Validation.HasError属性为true,触发控件的错误样式(默认就是红色边框),同时也会显示你看到的错误提示。
内容的提问来源于stack exchange,提问作者raihane

