WPF前台数据验证(红框)Validation.ErrorTemplate 附加属性
WPF 显示验证错误的默认方式是在控件周围绘制红色边框。通常需要对此方法进行自定义,以通过其他方式来显示错误。而且,默认情况下不会显示与验证错误关联的错误消息。常见的要求是仅当存在验证错误时才在工具提示中显示错误消息。通过将 Styles 和一组与验证关联的附加属性进行组合,可以相当轻松地自定义验证错误显示。

前台xaml:
- <ResourceDictionary
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
- <!-- 应该在此定义资源字典条目。-->
- <LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" StartPoint="0,0" MappingMode="Absolute">
- <GradientStop Color="#ABADB3" Offset="0.05"/>
- <GradientStop Color="#E2E3EA" Offset="0.07"/>
- <GradientStop Color="#E3E9EF" Offset="1"/>
- </LinearGradientBrush>
- <ControlTemplate x:Key="validationTemplate">
- </ControlTemplate>
- <Style BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
- <Setter Property="Validation.ErrorTemplate" Value="{StaticResource validationTemplate}" />
- <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
- <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
- <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
- <Setter Property="BorderThickness" Value="1"/>
- <Setter Property="Padding" Value="1"/>
- <Setter Property="AllowDrop" Value="true"/>
- <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate TargetType="{x:Type TextBox}">
- <Grid x:Name="root">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*"/>
- <ColumnDefinition Width="1"/>
- </Grid.ColumnDefinitions>
- <!--<Border x:Name="Border" Background="White" BorderBrush="Gray" BorderThickness="0" Padding="2" CornerRadius="1">-->
- <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" RenderMouseOver="{TemplateBinding IsMouseOver}">
- <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
- </Microsoft_Windows_Themes:ListBoxChrome>
- <!--</Border>-->
- <Border x:Name="border" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1" Visibility="Collapsed" HorizontalAlignment="Stretch" Margin="0" Width="Auto">
- <Grid Background="Transparent" HorizontalAlignment="Right" Height="12" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12">
- <Path Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C" Margin="1,3,0,0"/>
- <Path Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff" Margin="1,3,0,0"/>
- </Grid>
- </Border>
- <Popup x:Name="popup" Placement="Right" IsOpen="False">
- <Border x:Name="border1_Copy" Width="Auto" Height="Auto" Background="Red" BorderThickness="0" >
- <TextBlock TextWrapping="NoWrap" Text="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"/>
- </Border>
- <!--<Grid Width="50" Height="20" Background="Red"/>-->
- </Popup>
- <!--<Popup x:Name="popup" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" IsOpen="False" StaysOpen="True" AllowsTransparency="True">
- <Border x:Name="border1_Copy" BorderThickness="1" Margin="0" Background="Red" CornerRadius="2" HorizontalAlignment="Stretch" Opacity="0" RenderTransformOrigin="0.5,0.5" Height="Auto" Width="Auto">
- <Border.RenderTransform>
- <TransformGroup>
- <ScaleTransform/>
- <SkewTransform/>
- <RotateTransform/>
- <TranslateTransform X="10"/>
- </TransformGroup>
- </Border.RenderTransform>
- <Border.Effect>
- <DropShadowEffect Direction="-90" BlurRadius="5" Color="#FF808080" ShadowDepth="1"/>
- </Border.Effect>
- <TextBlock TextWrapping="NoWrap" Text="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"/>
- </Border>
- </Popup>-->
- </Grid>
- <ControlTemplate.Triggers>
- <Trigger Property="Validation.HasError" Value="True">
- <Setter Property="Visibility" TargetName="border" Value="Visible"/>
- </Trigger>
- <MultiTrigger>
- <MultiTrigger.Conditions>
- <Condition Property="Validation.HasError" Value="True"/>
- <Condition Property="IsFocused" Value="True"/>
- </MultiTrigger.Conditions>
- <Setter Property="IsOpen" TargetName="popup" Value="True"/>
- </MultiTrigger>
- </ControlTemplate.Triggers>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- <!--<Style TargetType="TextBox">
- <Style.Triggers>
- <Trigger Property="Validation.HasError"
- Value="True">
- <Setter Property="ToolTip">
- <Setter.Value>
- <Binding Path="(Validation.Errors).CurrentItem.ErrorContent" RelativeSource="{x:Static RelativeSource.Self}" />
- </Setter.Value>
- </Setter>
- </Trigger>
- </Style.Triggers>
- </Style>-->
- </ResourceDictionary>
后台代码:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Navigation;
- using System.Windows.Shapes;
- namespace WpfApplication11111
- {
- /// <summary>
- /// UserControl2.xaml 的交互逻辑
- /// </summary>
- public partial class UserControl2 : UserControl
- {
- private UserInfo _UserInfo;
- public UserControl2()
- {
- InitializeComponent();
- this.Loaded += new RoutedEventHandler(UserControl2_Loaded);
- }
- void UserControl2_Loaded(object sender, RoutedEventArgs e)
- {
- _UserInfo = new UserInfo();
- this.DataContext = _UserInfo;
- }
- private void btnSave_Click(object sender, RoutedEventArgs e)
- {
- //txtName.Visibility = Visibility.Collapsed;
- UserControl1 _UserControl1 = new UserControl1();
- grid.Children.Add(_UserControl1);
- string _name = _UserInfo.Name;
- string _pass = _UserInfo.Pass;
- }
- }
- }
实体类:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ComponentModel;
- using System.ComponentModel.DataAnnotations;
- namespace WpfApplication11111
- {
- public class UserInfo : ValidationUtility, INotifyPropertyChanged
- {
- #region 数据更新通知
- public event PropertyChangedEventHandler PropertyChanged;
- private void NotifyPropertyChange(string propertyName)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
- }
- }
- #endregion
- private string _Name;
- [Required(ErrorMessage = "[登录名]内容不能为空!")]
- [StringLength(255, ErrorMessage = "[登录名]内容最大允许255个字符!")]
- [RegularExpression("^[A-Za-z0-9]+$", ErrorMessage = "[登录名]格式不正确!")]
- /// <summary>
- ///
- /// </summary>
- public string Name
- {
- get { return _Name; }
- set
- {
- //Validator.ValidateProperty(value, new ValidationContext(this, null, null) { MemberName = "Name" });
- //if (string.IsNullOrEmpty(value))
- //{
- // throw new Exception("用户名不能为空.");
- //}
- _Name = value;
- NotifyPropertyChange("Name");
- }
- }
- private string _Pass;
- [Required(ErrorMessage = "[密码]内容不能为空!")]
- [StringLength(255, ErrorMessage = "[密码]内容最大允许255个字符!")]
- [RegularExpression("^[A-Za-z0-9]+$", ErrorMessage = "[密码]格式不正确!")]
- /// <summary>
- ///
- /// </summary>
- public string Pass
- {
- get { return _Pass; }
- set
- {
- //if (string.IsNullOrEmpty(value))
- //{
- // throw new Exception("密码不能为空.");
- //}
- _Pass = value;
- NotifyPropertyChange("Pass");
- }
- }
- }
- }
ValidationUtility.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ComponentModel;
- using System.Reflection;
- using System.ComponentModel.DataAnnotations;
- namespace WpfApplication11111
- {
- public class ValidationUtility : IDataErrorInfo
- {
- public string Error
- {
- get { return _error; }
- }
- public string _error;
- public string this[string columnName]
- {
- get
- {
- Type tp = this.GetType();
- PropertyInfo pi = tp.GetProperty(columnName);
- var value = pi.GetValue(this, null);
- object[] Attributes = pi.GetCustomAttributes(false);
- if (Attributes != null && Attributes.Length > 0)
- {
- foreach (object attribute in Attributes)
- {
- if (attribute is ValidationAttribute)
- {
- ValidationAttribute vAttribute = attribute as ValidationAttribute;
- if (!vAttribute.IsValid(value))
- {
- _error = vAttribute.ErrorMessage;
- return _error;
- }
- }
- }
- }
- return null;
- }
- }
- }
- }
追加PasswordBox验证
- <Style TargetType="{x:Type PasswordBox}">
- <Setter Property="Validation.ErrorTemplate" Value="{StaticResource validationTemplate}" />
- <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
- <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
- <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
- <Setter Property="FontFamily" Value="Times New Roman"/>
- <Setter Property="PasswordChar" Value="●"/>
- <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
- <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
- <Setter Property="BorderThickness" Value="1"/>
- <Setter Property="HorizontalContentAlignment" Value="Left"/>
- <Setter Property="Padding" Value="1"/>
- <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
- <Setter Property="AllowDrop" Value="true"/>
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate TargetType="{x:Type PasswordBox}">
- <Grid x:Name="root">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*"/>
- <ColumnDefinition Width="1"/>
- </Grid.ColumnDefinitions>
- <!--<Border x:Name="Border" Background="White" BorderBrush="Gray" BorderThickness="0" Padding="2" CornerRadius="1">-->
- <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" RenderMouseOver="{TemplateBinding IsMouseOver}">
- <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
- </Microsoft_Windows_Themes:ListBoxChrome>
- <!--</Border>-->
- <Border x:Name="border" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1" Visibility="Collapsed" HorizontalAlignment="Stretch" Margin="0" Width="Auto">
- <Grid Background="Transparent" HorizontalAlignment="Right" Height="12" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12">
- <Path Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C" Margin="1,3,0,0"/>
- <Path Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff" Margin="1,3,0,0"/>
- </Grid>
- </Border>
- <Popup x:Name="popup" Placement="Right" IsOpen="False">
- <Border x:Name="border1_Copy" Width="Auto" Height="Auto" Background="Red" BorderThickness="0" >
- <TextBlock TextWrapping="NoWrap" Text="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"/>
- </Border>
- </Popup>
- </Grid>
- <ControlTemplate.Triggers>
- <Trigger Property="Validation.HasError" Value="True">
- <Setter Property="Visibility" TargetName="border" Value="Visible"/>
- </Trigger>
- <MultiTrigger>
- <MultiTrigger.Conditions>
- <Condition Property="Validation.HasError" Value="True"/>
- <Condition Property="IsFocused" Value="True"/>
- </MultiTrigger.Conditions>
- <Setter Property="IsOpen" TargetName="popup" Value="True"/>
- </MultiTrigger>
- </ControlTemplate.Triggers>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
代码下载地址:
WPF前台数据验证(红框)Validation.ErrorTemplate 附加属性的更多相关文章
- [WPF] 让第一个数据验证出错(Validation.HasError)的控件自动获得焦点
1. 需求 在上一篇文章 <在 ViewModel 中让数据验证出错(Validation.HasError)的控件获得焦点>中介绍了如何让 Validation.HasError 的控件 ...
- 【WPF】数据验证
原文:[WPF]数据验证 引言 数据验证在任何用户界面程序中都是不可缺少的一部分.在WPF中,数据验证更是和绑定紧紧联系在一起,下面简单介绍MVVM模式下常用的几种验证方式. 错误信息显示 ...
- [WPF 自定义控件]自定义一个“传统”的 Validation.ErrorTemplate
1. 什么是Validaion.ErrorTemplate 数据绑定模型允许您将与您Binding的对象相关联ValidationRules. 如果用户输入的值无效,你可能希望在应用程序 用户界面 ( ...
- [WPF] 在 ViewModel 中让数据验证出错(Validation.HasError)的控件获得焦点
1. 需求 在 MVVM 中 ViewModel 和 View 之间的交互通常都是靠 Icommand 和 INotifyPropertyChanged,不过有时候还会需要从 MVVM 中控制 Vie ...
- 测开之路一百五十五:jquery-validation前台数据验证
前面做的wtform验证是服务器端的验证,需要把数据传输到服务器,服务器验证后再吧结果传输到前端,网络慢的时候,用户体验不好,所以需要前端验证,且后端验证不能少 传统的js或者jquery如果要验证信 ...
- 【Win10】使用 ValidationAttribute 实现数据验证
WPF 中数据验证的方式多种多样,这里就不说了.但是,在 Windows Phone 8.1 Runtime 中,要实现数据验证,只能靠最基础的手动编写条件判断代码来实现.如果用过 ASP.NET M ...
- WPF 中 UserControl作为另一个Process宿主到Window里, ErrorTemplate的默认红框没有出现
最近做WPF项目遇到一个问题, 我有2个process, 一个Process里只有Usercontrol, 另一个Process获取前一个Process中Usercontrol并host到当前的win ...
- WPF数据验证
当填写表单时,需要对填写的内容进行验证,检查数据是否符合要求,比如字符串的长度.日期的格式.数字等.WPF支持自定义验证规则,并提供可视化反馈,以便在输入无效值时向用户发出通知. 下面的示例将演示一个 ...
- WPF中的数据验证
数据验证 WPF的Binding使得数据能够在数据源和目标之间流通,在数据流通的中间,便能够对数据做一些处理. 数据转换和数据验证便是在数据从源到目标 or 从目标到源 的时候对数据的验证和转换. V ...
随机推荐
- FOJ Problem 2257 Saya的小熊饼干
...
- javap的基本用法
参考:http://www.cnblogs.com/beautiful-code/p/6424977.html javap是JDK自带的反汇编器,可以查看java编译器为我们生成的字节码.通过它,我们 ...
- 【Linux】多进程与多线程之间的区别
http://blog.csdn.net/byrsongqq/article/details/6339240 网络编程中设计并发服务器,使用多进程与多线程 ,请问有什么区别? 答案一: 1,进程:子 ...
- android 设置app root权限简单方法
vim frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java +709 private static void ...
- https的简单学习
HTTPS介绍: (全称:Hyper Text Transfer Protocol over Secure Socket Layer 或 Hypertext Transfer Protocol Sec ...
- LeetCode OJ--Unique Paths II **
https://oj.leetcode.com/problems/unique-paths-ii/ 图的深搜,有障碍物,有的路径不通. 刚开始想的时候用组合数算,但是公式没有推导出来. 于是用了深搜, ...
- AC日记——圆桌聚餐 cogs 729
729. [网络流24题] 圆桌聚餐 ★★ 输入文件:roundtable.in 输出文件:roundtable.out 评测插件时间限制:1 s 内存限制:128 MB «问题描述: ...
- AC日记——教辅的组成 洛谷 P1231
题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书 ...
- inotify+rsync的初步配置
inotify的简单配置 Linux内核从2.6.13开始,引入了inotify机制.通过intofity机制,能够对文件系统的变化进行监控,如对文件进行创建.删除.修改等操作,可以及时通知应用程序 ...
- Windows Phone 8 适应多屏分辨率
Windows Phone 8 比较 windows phone 7 来说有很多功能及性能上的提升例如支持多核 CUP.支持SD卡.多种分辨率. 显然WP7 WVGA - 480x800 的已经不能完 ...