WPF前台数据验证(红框)Validation.ErrorTemplate 附加属性
2013-02-18 18:30
441 查看
WPF 显示验证错误的默认方式是在控件周围绘制红色边框。通常需要对此方法进行自定义,以通过其他方式来显示错误。而且,默认情况下不会显示与验证错误关联的错误消息。常见的要求是仅当存在验证错误时才在工具提示中显示错误消息。通过将
Styles 和一组与验证关联的附加属性进行组合,可以相当轻松地自定义验证错误显示。
后台代码:
http://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
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>
代码下载地址:
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
相关文章推荐
- WPF前台数据验证(红框)Validation.ErrorTemplate 附加属性
- WPF前台数据验证(红框)Validation.ErrorTemplate 附加属性
- WPF数据验证(2)—— DataErrorValidationRule 验证规则
- WPF ValidationRule 触发ErrorTemplate 的注意事项
- [WPF系列]-数据邦定之DataTemplate 根据对象属性切换模板
- WPF IDataErrorInfo使用-数据对象上验证
- 使用EF保存数据时 提示: 其他信息: 对一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationErrors”属性。
- Silverlight实例教程 - Validation数据验证基础属性和事件
- Silverlight实例教程 - Validation数据验证基础属性和事件
- WPF 数据模板DataType属性的使用,不用指定ItemTemplate
- WPF ValidationRule 触发ErrorTemplate 的注意事项
- Silverlight实例教程 - Validation数据验证基础属性和事件
- WPF数据验证(1)—— ExceptionValidationRule验证规则
- Silverlight实例教程 - Validation数据验证基础属性和事件
- WPF ValidationRule 触发ErrorTemplate 的注意事项
- Silverlight实例教程 - Validation数据验证基础属性和事件(转载)
- WPF 数据验证失效 Validation Fail on TabControl
- WPF Binding Validation 数据验证
- WPF数据验证(6)—— IDataErrorInfo + DataAnnotations
- Silverlight实例教程 - Validation用户提交数据验证捕获