当前位置: 首页 > news >正文

ObservableValidator自定义错误样式

1. wpf sample部分代码如下

只修改MainWindow.xaml,其他代码在上一篇

<Window x:Class="ObservableValidatorSample.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:ObservableValidatorSample"mc:Ignorable="d"Title="ObservableValidator 示例" Height="450" Width="800"><Window.Resources><!-- 自定义错误显示样式 --><Style TargetType="TextBox"><Style.Triggers><Trigger Property="Validation.HasError" Value="True"><Setter Property="ToolTip"Value="{Binding (Validation.Errors)[0].ErrorContent,RelativeSource={RelativeSource Self}}" /></Trigger></Style.Triggers></Style><ControlTemplate x:Key="ValidationErrorTemplate"><DockPanel LastChildFill="True"><TextBlock Foreground="Red" FontSize="12" Margin="5,0,0,0"DockPanel.Dock="Bottom"Text="{Binding [0].ErrorContent}" /><AdornedElementPlaceholder/></DockPanel></ControlTemplate></Window.Resources><Window.DataContext><local:PersonViewModel/></Window.DataContext><StackPanel Margin="20" VerticalAlignment="Center"><TextBlock Text="姓名:"/><TextBoxMargin="0,5,0,10"Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}"Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" /><TextBlock Text="年龄:"/><TextBoxMargin="0,5,0,10"Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}"Text="{Binding Age, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" /><Button Content="触发全部验证"HorizontalAlignment="Left"Width="150"Click="OnValidateClick" /></StackPanel>
</Window>

运行效果如下

2. 解释核心知识点

1. INotifyDataErrorInfo 机制

作用

INotifyDataErrorInfo 是 WPF 和其他 XAML 框架支持的数据验证接口,主要用于通知绑定系统某个属性的验证错误,从而让 UI 能够动态响应并显示错误。


关键成员

  • 事件:
    ErrorsChanged
    发生在某个属性的验证错误状态发生变化时触发。UI 监听这个事件,更新显示。

  • 方法:
    IEnumerable GetErrors(string propertyName)
    返回指定属性当前的错误信息列表。

  • 属性:
    bool HasErrors
    表示是否存在任何验证错误。


工作流程

  1. ViewModel 实现了 INotifyDataErrorInfo 后,绑定系统会自动调用 GetErrors 查询错误信息,决定控件是否有错误。

  2. ViewModel 在属性值变化时执行验证逻辑,更新内部错误状态。

  3. 如果错误状态变化,ViewModel 触发 ErrorsChanged 事件,通知 UI 重新请求错误数据。

  4. UI 根据错误存在与否,应用不同的视觉样式(例如红框)和显示错误消息。


CommunityToolkit.Mvvm 的 ObservableValidator

  • ObservableValidator 是对 INotifyDataErrorInfo 的封装,实现了错误管理和触发 ErrorsChanged

  • 你只需要在属性上添加数据注解(如 [Required][Range]),调用 ValidateProperty / ValidateAllProperties,它会自动完成验证并触发事件。

  • NotifyDataErrorInfo 属性可以让属性变化时自动触发验证。


2. WPF 自定义验证错误样式原理

默认行为

  • 绑定启用验证(例如设置了 ValidatesOnDataErrors=True)时,WPF 会根据绑定的验证状态自动设置控件的 Validation.HasError 属性。

  • Validation.HasError 是一个附加属性,表示当前控件是否有错误。


ErrorTemplate

  • WPF 中控件有一个 Validation.ErrorTemplate 属性,可以自定义控件出错时的视觉表现。

  • 默认 ErrorTemplate 会显示一个红色感叹号图标在控件右侧。

  • 你可以自定义 ErrorTemplate,实现例如:

    • 红色边框高亮控件

    • 在控件下方显示错误文本

    • 自定义图标或动画


ErrorTemplate 的工作原理

  • ErrorTemplate 是一个 ControlTemplate,通常包含一个 AdornedElementPlaceholder,它占位显示被装饰的控件本体。

  • 当控件 Validation.HasError == true 时,WPF 自动在控件外层添加一个装饰层(Adorner),显示 ErrorTemplate

  • 这个装饰层不影响控件布局,只覆盖显示层。


绑定错误内容到 UI

  • 绑定错误信息时,通常用表达式绑定:

    Text="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource Self}}"
  • 这里用的是 Validation.Errors 附加属性,它存储了控件所有的错误信息集合。

  • 通过这种绑定,错误提示文本可以动态显示当前的第一个错误内容。

http://www.lryc.cn/news/589438.html

相关文章:

  • 从知识变现到创始人IP:知识付费的进阶之路
  • zip 加密压缩文件的原理是什么?
  • 【Java】【企业级应用】学生信息管理系统项目介绍
  • 算法入门:BFS与DFS详解(C++实现)
  • 【kubernetes】--ConfigMap
  • 极致cms多语言建站|设置主站默认语言与设置后台固定语言为中文
  • frp内网穿透(二)
  • 牛客:HJ20 密码验证合格程序[华为机考][字符串]
  • 一般芯片电气特性中Flash参数达到其最大值的条件是什么?
  • 【人工智能99问】激活函数有哪些,如何选择使用哪个激活函数?(5/99)
  • 全新 Python 项目托管到 Gitee 私有仓库完整流程(带详细命令注释)
  • 【PTA数据结构 | C语言版】构造二叉树
  • 软件质量概述
  • 使用 pdb 来 debug 调试 python 程序
  • I3C通信驱动开发注意事项
  • Linux715 磁盘管理:逻辑卷
  • golang二级缓存示例
  • 随机奖励能提升Qwen数学表现?本质是数据污染
  • NuGet01-安装及使用
  • Linux下编译海思WS63 SDK全攻略
  • 关于Linux下Cursor的使用
  • 如何设计实现开发自助重启工具-01-设计篇
  • 代码随想录八股文训练营总结
  • lesson14:Python的推导式
  • 2025-07-15 李沐深度学习6——Softmax回归
  • 项目:简单学生成绩管理系统设计
  • Nginx配置反向代理
  • 深入解析:磁盘级文件与内存级(被打开)文件的本质区别与联系
  • 脚手架新建Vue2/Vue3项目时,项目文件内容的区别
  • k8s环境使用Operator部署Seaweedfs集群(上)