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 ...
随机推荐
- JavaWeb学习总结(十七)——JSP中的九个内置对象(转)
一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...
- 【CF707B】Bakery(想法题)
题意: 有N个城市,M条无向边,其中有K个城市是仓库 现在要在非仓库的城市中选择一家开面包店,使得其最少与一个仓库联通,且到所有仓库距离的最小值最小 (1 ≤ n, m ≤ 10^5, 0 ≤ k ≤ ...
- 在 Ubuntu 下使用 com port, serial port
1. Install putty 2. Insert serial-to-usb converter cable converter to NB or PC 3. check converter un ...
- 问题:Linux 输入任何命令都显示 -bash: fork: Cannot allocate memory
应该是某个程序吃掉了所有的内存,只能重启
- 51nod 1201 整数划分
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1201 DP转移方程:dp[i][j] = dp[i-j][j]+dp[i ...
- window.getComputedStyle——ref
componentDidMount() { const LeftHeight = window.getComputedStyle(this.leftDom).height; console.log(L ...
- 做IT这几年,我整理了这些干货想要送给你!
没有一条路是容易的,特别是转行计算机这条路. 松哥接触过很多转行做开发的小伙伴,我了解到很多转行人的不容易,记得松哥大二时刚刚决定转行计算机,完全不知道这些东西到底应该怎么学,每天就是抱着书啃,书倒是 ...
- BZOJ——2134: 单选错位
http://www.lydsy.com/JudgeOnline/problem.php?id=2134 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: ...
- 小程序使用wxParse插件解析html标签图片间距问题
转自:https://www.cnblogs.com/likun123/p/9543376.html 小程序解析html标签,就需要用到wxParse啦.但是在解析连续图片的时候,会发现图片之间会有间 ...
- 【java】Java transient关键字使用小记【转】
转载地址:https://www.cnblogs.com/lanxuezaipiao/p/3369962.html 1. transient的作用及使用方法 我们都知道一个对象只要实现了Seriliz ...