分享

WPF前台数据验证(红框)Validation.ErrorTemplate 附加属性

 昵称10504424 2013-02-19

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


前台xaml:

  1. <ResourceDictionary  
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">  
  4.     <!-- 应该在此定义资源字典条目。-->  
  5.     <LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" StartPoint="0,0" MappingMode="Absolute">  
  6.         <GradientStop Color="#ABADB3" Offset="0.05"/>  
  7.         <GradientStop Color="#E2E3EA" Offset="0.07"/>  
  8.         <GradientStop Color="#E3E9EF" Offset="1"/>  
  9.     </LinearGradientBrush>  
  10.     <ControlTemplate x:Key="validationTemplate">  
  11.   
  12.     </ControlTemplate>  
  13.     <Style BasedOn="{x:Null}" TargetType="{x:Type TextBox}">  
  14.         <Setter Property="Validation.ErrorTemplate" Value="{StaticResource validationTemplate}" />  
  15.         <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>  
  16.         <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>  
  17.         <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>  
  18.         <Setter Property="BorderThickness" Value="1"/>  
  19.         <Setter Property="Padding" Value="1"/>  
  20.         <Setter Property="AllowDrop" Value="true"/>  
  21.         <Setter Property="FocusVisualStyle" Value="{x:Null}"/>  
  22.         <Setter Property="Template">  
  23.             <Setter.Value>  
  24.                 <ControlTemplate TargetType="{x:Type TextBox}">  
  25.                     <Grid x:Name="root">  
  26.                         <Grid.ColumnDefinitions>  
  27.                             <ColumnDefinition Width="*"/>  
  28.                             <ColumnDefinition Width="1"/>  
  29.                         </Grid.ColumnDefinitions>  
  30.                         <Border x:Name="Border" Background="White" BorderBrush="Gray" BorderThickness="0" Padding="2" CornerRadius="1">  
  31.                             <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" RenderMouseOver="{TemplateBinding IsMouseOver}">  
  32.                                 <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>  
  33.                             </Microsoft_Windows_Themes:ListBoxChrome>  
  34.                         </Border>  
  35.                         <Border x:Name="border"  BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1" Visibility="Collapsed"  HorizontalAlignment="Stretch" Margin="0" Width="Auto">  
  36.   
  37.                             <Grid Background="Transparent" HorizontalAlignment="Right" Height="12" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12">  
  38.                                 <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"/>  
  39.                                 <Path Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff" Margin="1,3,0,0"/>  
  40.                             </Grid>  
  41.                         </Border>  
  42.                         <Popup x:Name="popup" Placement="Right" IsOpen="False">  
  43.                             <Border x:Name="border1_Copy" Width="Auto" Height="Auto" Background="Red" BorderThickness="0" >  
  44.                                 <TextBlock TextWrapping="NoWrap" Text="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"/>  
  45.                             </Border>  
  46.                             <!--<Grid Width="50" Height="20" Background="Red"/>-->  
  47.   
  48.                         </Popup>  
  49.                         <!--<Popup x:Name="popup"  Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}"  Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" IsOpen="False" StaysOpen="True" AllowsTransparency="True">  
  50.                             <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">  
  51.                                 <Border.RenderTransform>  
  52.                                     <TransformGroup>  
  53.                                         <ScaleTransform/>  
  54.                                         <SkewTransform/>  
  55.                                         <RotateTransform/>  
  56.                                         <TranslateTransform X="10"/>  
  57.                                     </TransformGroup>  
  58.                                 </Border.RenderTransform>  
  59.                                 <Border.Effect>  
  60.                                     <DropShadowEffect Direction="-90" BlurRadius="5" Color="#FF808080" ShadowDepth="1"/>  
  61.                                 </Border.Effect>  
  62.                                 <TextBlock TextWrapping="NoWrap" Text="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"/>  
  63.                             </Border>  
  64.                         </Popup>-->  
  65.                     </Grid>  
  66.                     <ControlTemplate.Triggers>  
  67.                         <Trigger Property="Validation.HasError" Value="True">  
  68.                             <Setter Property="Visibility" TargetName="border" Value="Visible"/>  
  69.                         </Trigger>  
  70.                         <MultiTrigger>  
  71.                             <MultiTrigger.Conditions>  
  72.                                 <Condition Property="Validation.HasError" Value="True"/>  
  73.                                 <Condition Property="IsFocused" Value="True"/>  
  74.                             </MultiTrigger.Conditions>  
  75.                             <Setter Property="IsOpen" TargetName="popup" Value="True"/>  
  76.                         </MultiTrigger>  
  77.                     </ControlTemplate.Triggers>  
  78.                 </ControlTemplate>  
  79.             </Setter.Value>  
  80.         </Setter>  
  81.     </Style>  
  82.     <!--<Style TargetType="TextBox">  
  83.         <Style.Triggers>  
  84.   
  85.             <Trigger Property="Validation.HasError"   
  86.               Value="True">  
  87.   
  88.                 <Setter Property="ToolTip">  
  89.   
  90.                     <Setter.Value>  
  91.   
  92.                         <Binding Path="(Validation.Errors).CurrentItem.ErrorContent" RelativeSource="{x:Static RelativeSource.Self}" />  
  93.   
  94.                     </Setter.Value>  
  95.   
  96.                 </Setter>  
  97.   
  98.             </Trigger>  
  99.   
  100.         </Style.Triggers>  
  101.   
  102.     </Style>-->  
  103. </ResourceDictionary>  

后台代码:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Windows;  
  6. using System.Windows.Controls;  
  7. using System.Windows.Data;  
  8. using System.Windows.Documents;  
  9. using System.Windows.Input;  
  10. using System.Windows.Media;  
  11. using System.Windows.Media.Imaging;  
  12. using System.Windows.Navigation;  
  13. using System.Windows.Shapes;  
  14.   
  15. namespace WpfApplication11111  
  16. {  
  17.     /// <summary>   
  18.     /// UserControl2.xaml 的交互逻辑   
  19.     /// </summary>   
  20.     public partial class UserControl2 : UserControl  
  21.     {  
  22.         private UserInfo _UserInfo;  
  23.         public UserControl2()  
  24.         {  
  25.             InitializeComponent();  
  26.             this.Loaded += new RoutedEventHandler(UserControl2_Loaded);  
  27.         }  
  28.   
  29.         void UserControl2_Loaded(object sender, RoutedEventArgs e)  
  30.         {  
  31.             _UserInfo = new UserInfo();  
  32.             this.DataContext = _UserInfo;  
  33.         }  
  34.   
  35.         private void btnSave_Click(object sender, RoutedEventArgs e)  
  36.         {  
  37.             //txtName.Visibility = Visibility.Collapsed;   
  38.             UserControl1 _UserControl1 = new UserControl1();  
  39.             grid.Children.Add(_UserControl1);  
  40.             string _name = _UserInfo.Name;  
  41.             string _pass = _UserInfo.Pass;  
  42.         }  
  43.     }  
  44. }  

实体类:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.ComponentModel;  
  6. using System.ComponentModel.DataAnnotations;  
  7.   
  8. namespace WpfApplication11111  
  9. {  
  10.     public class UserInfo : ValidationUtility, INotifyPropertyChanged  
  11.     {  
  12.         #region 数据更新通知   
  13.   
  14.         public event PropertyChangedEventHandler PropertyChanged;  
  15.   
  16.         private void NotifyPropertyChange(string propertyName)  
  17.         {  
  18.             if (PropertyChanged != null)  
  19.             {  
  20.                 PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));  
  21.             }  
  22.         }  
  23.  
  24.         #endregion   
  25.   
  26.         private string _Name;  
  27.   
  28.         [Required(ErrorMessage = "[登录名]内容不能为空!")]  
  29.         [StringLength(255, ErrorMessage = "[登录名]内容最大允许255个字符!")]  
  30.         [RegularExpression("^[A-Za-z0-9]+$", ErrorMessage = "[登录名]格式不正确!")]  
  31.         /// <summary>   
  32.         ///    
  33.         /// </summary>   
  34.         public string Name  
  35.         {  
  36.             get { return _Name; }  
  37.             set  
  38.             {  
  39.                 //Validator.ValidateProperty(value, new ValidationContext(this, null, null) { MemberName = "Name" });   
  40.                 //if (string.IsNullOrEmpty(value))   
  41.                 //{   
  42.                 //    throw new Exception("用户名不能为空.");   
  43.                 //}   
  44.                 _Name = value;  
  45.                 NotifyPropertyChange("Name");  
  46.             }  
  47.         }  
  48.   
  49.         private string _Pass;  
  50.         [Required(ErrorMessage = "[密码]内容不能为空!")]  
  51.         [StringLength(255, ErrorMessage = "[密码]内容最大允许255个字符!")]  
  52.         [RegularExpression("^[A-Za-z0-9]+$", ErrorMessage = "[密码]格式不正确!")]  
  53.         /// <summary>   
  54.         ///    
  55.         /// </summary>   
  56.         public string Pass  
  57.         {  
  58.             get { return _Pass; }  
  59.             set  
  60.             {  
  61.                 //if (string.IsNullOrEmpty(value))   
  62.                 //{   
  63.                 //    throw new Exception("密码不能为空.");   
  64.                 //}   
  65.                 _Pass = value;  
  66.                 NotifyPropertyChange("Pass");  
  67.             }  
  68.         }  
  69.   
  70.     }  
  71. }  

ValidationUtility.cs

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.ComponentModel;  
  6. using System.Reflection;  
  7. using System.ComponentModel.DataAnnotations;  
  8.   
  9. namespace WpfApplication11111  
  10. {  
  11.     public class ValidationUtility : IDataErrorInfo  
  12.     {  
  13.         public string Error  
  14.         {  
  15.             get { return _error; }  
  16.         }  
  17.   
  18.         public string _error;  
  19.   
  20.         public string this[string columnName]  
  21.         {  
  22.             get  
  23.             {  
  24.                 Type tp = this.GetType();  
  25.                 PropertyInfo pi = tp.GetProperty(columnName);  
  26.                 var value = pi.GetValue(thisnull);  
  27.                 object[] Attributes = pi.GetCustomAttributes(false);  
  28.                 if (Attributes != null && Attributes.Length > 0)  
  29.                 {  
  30.                     foreach (object attribute in Attributes)  
  31.                     {  
  32.                         if (attribute is ValidationAttribute)  
  33.                         {  
  34.                             ValidationAttribute vAttribute = attribute as ValidationAttribute;  
  35.                             if (!vAttribute.IsValid(value))  
  36.                             {  
  37.                                 _error = vAttribute.ErrorMessage;  
  38.                                 return _error;  
  39.                             }  
  40.                         }  
  41.                     }  
  42.                 }  
  43.                 return null;  
  44.             }  
  45.         }  
  46.     }  
  47. }  

代码下载地址:

http://download.csdn.net/detail/hwt0101/5070730

相关地址:

http://msdn.microsoft.com/zh-cn/magazine/ff714593.aspx

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多