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 ...
随机推荐
- hdu 1007 Quoit Design 分治求最近点对
Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- jquery 日期插件
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 视音频数据处理入门:RGB、YUV像素数据处理【转】
转自:http://blog.csdn.net/leixiaohua1020/article/details/50534150 ==================================== ...
- PHP读取APK的包信息,包括包名,应用名,权限,LOGO等
[转]PHP读取APK的包信息,包括包名,应用名,权限,LOGO等 声明本文转自: 原文链接:https://www.jb51.net/article/53780.htm: 感谢分享! <?ph ...
- python笔记4:高级特性
4 高级特性 4.1 切片 [:] *注:-- list和tuple,字符串都支持切片 4.2 迭代 Iteration for ... in 及 for ... in if 两个变量迭代时, 例1 ...
- HDU 1018.Big Number-Stirling(斯特林)公式 取N阶乘近似值
最近一堆题目要补,一直咸鱼,补了一堆水题都没必要写题解.备忘一下这个公式. Stirling公式的意义在于:当n足够大时,n!计算起来十分困难,虽然有很多关于n!的等式,但并不能很好地对阶乘结果进行估 ...
- (49)C# npoi-word
//新建段落 XWPFParagraph p1 = doc.CreateParagraph(); //对齐方式 p1.SetAlignment(ParagraphAlignment.LEFT); p1 ...
- Go语言入门——数组、切片和映射(下)
上篇主要介绍了Go语言里面常见的复合数据类型的声明和初始化. 这篇主要针对数组.切片和映射这些复合数据类型从其他几个方面介绍比较下. 1.遍历 不管是数组.切片还是映射结构,都是一种集合类型,要从这些 ...
- 洛谷——P2296 寻找道路
P2296 寻找道路 题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点 ...
- awk理论详解、实战
答疑解惑: 为什么用awk取IP的时候用$4? ifconfig eth0 | awk -F '[ :]+' 'NR==2{print $4}' IP第二行内容如下: inet addr:10.0.0 ...