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 ...
随机推荐
- scrapy之小试身手
要爬取的网址是:http://quotes.toscrape.com/ 磕磕绊绊的写完了 spiders import scrapy from kkk.items import * class Quo ...
- bzoj 2437[Noi2011]兔兔与蛋蛋 黑白染色二分图+博弈+匈牙利新姿势
noi2011 兔兔与蛋蛋 题目大意 直接看原题吧 就是\(n*m\)的格子上有一些白棋和一些黑棋和唯一一个空格 兔兔先手,蛋蛋后手 兔兔要把与空格相邻的其中一个白棋移到空格里 蛋蛋要把与空格相邻的其 ...
- codeforces练习
DZY Loves Colors Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u S ...
- 【HDOJ6229】Wandering Robots(马尔科夫链,set)
题意:给定一个n*n的地图,上面有k个障碍点不能走,有一个机器人从(0,0)出发,每次等概率的不动或者往上下左右没有障碍的地方走动,问走无限步后停在图的右下部的概率 n<=1e4,k<=1 ...
- PHP获取今天开始和结束的时间戳
$t = time();$start = mktime(0,0,0,date("m",$t),date("d",$t),date("Y",$ ...
- 在IOS11中position:fixed弹出框中的input出现光标错位的问题
问题出现的背景: 在IOS11中position:fixed弹出框中的input出现光标错位的问题 解决方案 一.设计交互方面最好不要让弹窗中出现input输入框: 二.前端处理此兼容性的方案思路: ...
- Codeforces 804D Expected diameter of a tree(树的直径 + 二分 + map查询)
题目链接 Expected diameter of a tree 题目意思就是给出一片森林, 若把任意两棵树合并(合并方法为在两个树上各自任选一点然后连一条新的边) 求这棵新的树的树的直径的期望长度. ...
- 嗅探X-Windows服务按键工具xspy
嗅探X-Windows服务按键工具xspy X-Windows完整名字是X Windows图形用户接口.它是一种计算机软件系统和网络协议.它为联网计算机提供了一个基础的图形用户界面(GUI)和丰富 ...
- 1.搭建maven,eclipse创建maven项目
1.下载maven包,下载地址为:http://maven.apache.org/download.cgi 2.解压zip包 3.eclipse 引入maven: window-Preferences ...
- Leetcode总结之Graph
package Graph; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections ...