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; } } }}
代码下载地址:
http://download.csdn.net/detail/hwt0101/5070730相关地址:
http://msdn.microsoft.com/zh-cn/magazine/ff714593.aspxhttp://msdn.microsoft.com/zh-cn/library/system.windows.controls.validation.errortemplate(v=vs.90).aspx
http://msdn.microsoft.com/en-us/library/ms752068(v=vs.100).aspx
http://wpf.codeplex.com/releases/view/14962