WPF 数据绑定之ValidationRule数据校验综合Demo
一、概述
我们利用ValidationRule以及ErrorTemplate来制作一个简单的表单验证。
二、Demo
核心思想:我们在ValidationRule中的Validate函数中进行验证,然后将验证结果存放至一个预先定义好的全局资源中,这样其他控件就可以根据验证结果来进行相应的处理,代码参见以下:
using System.ComponentModel; using System.Globalization; using System.Text.RegularExpressions; using System.Windows; using System.Windows.Controls; namespace BindingDemo5ValidationRuleDemo { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private string nickName; public string NickName { get { return nickName; } set { nickName = value; } } private string phoneNumber; public string PhoneNumber { get { return phoneNumber; } set { phoneNumber = value; } } private string password; public string Password { get { return password; } set { password = value; } } private string confirmPassword; public string ConfirmPassword { get { return confirmPassword; } set { confirmPassword = value; } } public MainWindow() { InitializeComponent(); this.DataContext = this; } private void Button_Click(object sender, RoutedEventArgs e) { MessageBox.Show(NickName); } } public class ValidationOutput : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnNotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } private bool isAllValid = true;//Indicate if all elements is valid public bool IsAllValid { get { return isAllValid; } set { isAllValid = value; OnNotifyPropertyChanged("IsAllValid"); } } private string errorMsg4NickName; public string ErrorMsg4NickName { get { return errorMsg4NickName; } set { errorMsg4NickName = value; OnNotifyPropertyChanged("ErrorMsg4NickName"); } } private bool isShow4NickName; public bool IsShow4NickName { get { return isShow4NickName; } set { isShow4NickName = value; OnNotifyPropertyChanged("IsShow4NickName"); } } private string errorMsg4PhoneNumber; public string ErrorMsg4PhoneNumber { get { return errorMsg4PhoneNumber; } set { errorMsg4PhoneNumber = value; OnNotifyPropertyChanged("ErrorMsg4PhoneNumber"); } } private bool isShow4PhoneNumber; public bool IsShow4PhoneNumber { get { return isShow4PhoneNumber; } set { isShow4PhoneNumber = value; OnNotifyPropertyChanged("IsShow4PhoneNumber"); } } private bool isPhoneNumberValid; public bool IsPhoneNumberValid { get { return isPhoneNumberValid; } set { isPhoneNumberValid = value; OnNotifyPropertyChanged("IsPhoneNumberValid"); } } private bool isNickNameValid; public bool IsNickNameValid { get { return isNickNameValid; } set { isNickNameValid = value; OnNotifyPropertyChanged("IsNickNameValid"); } } private string errorMsg4Password; public string ErrorMsg4Password { get { return errorMsg4Password; } set { errorMsg4Password = value; OnNotifyPropertyChanged("ErrorMsg4Password"); } } private bool isPasswordValid; public bool IsPasswordValid { get { return isPasswordValid; } set { isPasswordValid = value; OnNotifyPropertyChanged("IsPasswordValid"); } } private string password; public string Password { get { return password; } set { password = value; OnNotifyPropertyChanged("Password"); } } private string errorMsg4ConfirmPassword; public string ErrorMsg4ConfirmPassword { get { return errorMsg4ConfirmPassword; } set { errorMsg4ConfirmPassword = value; OnNotifyPropertyChanged("ErrorMsg4ConfirmPassword"); } } private bool isConfirmPasswordValid; public bool IsConfirmPasswordValid { get { return isConfirmPasswordValid; } set { isConfirmPasswordValid = value; OnNotifyPropertyChanged("IsConfirmPasswordValid"); } } } public class RegisterValidationRule : ValidationRule { private ValidationOutput validationOutput = null; public ValidationOutput ValidationOutput { get { return validationOutput; } set { validationOutput = value; } } private string validateType; public string ValidateType { get { return validateType; } set { validateType = value; } } public bool IsLegalPhoneNumber(string phoneNumber) { return Regex.IsMatch(phoneNumber, @"^1[3578]\d{9}$"); } public override ValidationResult Validate(object value, CultureInfo cultureInfo) { if (ValidateType == "NickName") { string s = (string)value; if (s.Length < 6) { ValidationOutput.IsNickNameValid = false; ValidationOutput.IsAllValid = false; ValidationOutput.ErrorMsg4NickName = "Length should be longger than 6 characters"; return new ValidationResult(false, "Length should be longger than 6 characters"); } else { ValidationOutput.IsNickNameValid = true; ValidationOutput.IsAllValid = true; return new ValidationResult(true, null); } } else if(ValidateType == "PhoneNumber") { string s = (string)value; if (!IsLegalPhoneNumber(s)) { //ValidationOutput.IsShow4PhoneNumber = true; ValidationOutput.IsPhoneNumberValid = false; ValidationOutput.IsAllValid = false; ValidationOutput.ErrorMsg4PhoneNumber = "Phone number format is not correct"; return new ValidationResult(false, "Phone number format is not correct"); } else { ValidationOutput.IsShow4PhoneNumber = false; ValidationOutput.IsPhoneNumberValid = true; ValidationOutput.IsAllValid = true; return new ValidationResult(true, null); } } else if (ValidateType == "Password") { string myPassword = (string)value; ValidationOutput.Password = myPassword;//Store the password in a global resource, used for validating the confirm password if (myPassword.Length < 8) { ValidationOutput.IsPasswordValid = false; ValidationOutput.IsAllValid = false; ValidationOutput.ErrorMsg4Password = "Password length should be longger than 8 characters"; return new ValidationResult(false, "Password length should be longger than 8 characters"); } else { ValidationOutput.IsPasswordValid = true; ValidationOutput.IsAllValid = true; return new ValidationResult(true, null); } } else if (ValidateType == "ConfirmPassword") { string myConfirmPassword = (string)value; string myPassword = ValidationOutput.Password; if (myPassword != myConfirmPassword) { ValidationOutput.IsConfirmPasswordValid = false; ValidationOutput.IsAllValid = false; ValidationOutput.ErrorMsg4ConfirmPassword = "Password are not the same"; return new ValidationResult(false, "Password are not the same"); } else { ValidationOutput.IsConfirmPasswordValid = true; ValidationOutput.IsAllValid = true; return new ValidationResult(true, null); } } return new ValidationResult(true, null); } } }
<Window x:Class="BindingDemo5ValidationRuleDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:BindingDemo5ValidationRuleDemo" mc:Ignorable="d" Title="RegisterWindow" Height="369.738" Width="479.098"> <Window.Resources> <BooleanToVisibilityConverter x:Key="Bool2Visibility"/> <local:ValidationOutput x:Key="validateOutput" IsShow4NickName="False"></local:ValidationOutput> <ControlTemplate x:Key="validationTemplate"> <DockPanel> <AdornedElementPlaceholder Name="adorner"/> <Grid Margin="20 0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="30"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Ellipse Width="20" Height="20" Name="elps" Fill="Red"></Ellipse> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20" Foreground="White" Name="tbx" Text="!" ToolTip="{Binding ElementName=adorner, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}" > </TextBlock> </Grid> </DockPanel> </ControlTemplate> <Style x:Key="textBoxInError" TargetType="{x:Type TextBox}"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self},Path=(Validation.Errors)[0].ErrorContent}"/> <Setter Property="BorderBrush" Value="Red"></Setter> <Setter Property="BorderThickness" Value="2"></Setter> <Setter Property="Validation.ErrorTemplate" Value="{StaticResource validationTemplate}" /> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Border BorderThickness="1" BorderBrush="#FF1D3061" Margin="20"> <Grid > <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto" MinHeight="79"/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="141"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="100"/> </Grid.ColumnDefinitions> <TextBlock Text="昵 称:" FontSize="20" VerticalAlignment="Center" Foreground="#FF416293" Margin="10,14" Height="28"></TextBlock> <TextBlock Text="电 话:" FontSize="20" VerticalAlignment="Center" Foreground="#FF416293" Margin="10,14" Grid.Row="1" Height="28"></TextBlock> <TextBlock Text="密 码:" FontSize="20" VerticalAlignment="Center" Foreground="#FF416293" Margin="10,14" Grid.Row="2" Height="27"></TextBlock> <TextBlock Text="密 码 确 认:" FontSize="20" VerticalAlignment="Center" Foreground="#FF416293" Margin="10,15" Grid.Row="3" Height="26"></TextBlock> <TextBox FontSize="20" VerticalAlignment="Center" Margin="10,12" Grid.Column="1" Style="{StaticResource textBoxInError}" Height="32" > <TextBox.Text> <Binding Path="NickName" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:RegisterValidationRule ValidationOutput="{StaticResource validateOutput}" ValidateType="NickName"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBox FontSize="20" VerticalAlignment="Center" Margin="10,12" Grid.Column="1" Grid.Row="1" Name="tbxPhone" Style="{StaticResource textBoxInError}" Height="32" > <TextBox.Text> <Binding Path="PhoneNumber" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:RegisterValidationRule ValidationOutput="{StaticResource validateOutput}" ValidateType="PhoneNumber"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBox FontSize="20" VerticalAlignment="Center" Margin="10,11" Grid.Column="1" Grid.Row="2" Height="33" Style="{StaticResource textBoxInError}"> <TextBox.Text> <Binding Path="Password" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:RegisterValidationRule ValidationOutput="{StaticResource validateOutput}" ValidateType="Password"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBox FontSize="20" VerticalAlignment="Center" Margin="10,11" Grid.Column="1" Grid.Row="3" Height="34" Style="{StaticResource textBoxInError}"> <TextBox.Text> <Binding Path="ConfirmPassword" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:RegisterValidationRule ValidationOutput="{StaticResource validateOutput}" ValidateType="ConfirmPassword"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <Button Grid.Row="4" Grid.Column="2" Margin="8,18,8,14" Content="注册" Background="#FF2C6CA2" Foreground="White" Click="Button_Click" IsEnabled="{Binding Path=IsAllValid, Source={StaticResource validateOutput}}"></Button> <Grid Grid.Column="2" Margin="10,10" Visibility="{Binding Path=IsNickNameValid, Source={StaticResource validateOutput}, Converter={StaticResource Bool2Visibility}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="30"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Ellipse Width="20" Height="20" Fill="Green"></Ellipse> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" Foreground="White">√</TextBlock> <!--<TextBlock VerticalAlignment="Center" FontSize="20" Foreground="Red" Grid.Column="1" Text="{Binding Path=ErrorMsg4NickName, Source={StaticResource validateOutput}}" > </TextBlock>--> </Grid> <Grid Grid.Column="2" Grid.Row="1" Margin="10,10" Visibility="{Binding Path=IsPhoneNumberValid, Source={StaticResource validateOutput}, Converter={StaticResource Bool2Visibility}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="30"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Ellipse Width="20" Height="20" Fill="Green"></Ellipse> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" Foreground="White">√</TextBlock> </Grid> <Grid Grid.Column="2" Grid.Row="2" Margin="10,10" Visibility="{Binding Path=IsPasswordValid, Source={StaticResource validateOutput}, Converter={StaticResource Bool2Visibility}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="30"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Ellipse Width="20" Height="20" Fill="Green"></Ellipse> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" Foreground="White">√</TextBlock> </Grid> <Grid Grid.Column="2" Grid.Row="3" Margin="10,10" Visibility="{Binding Path=IsConfirmPasswordValid, Source={StaticResource validateOutput}, Converter={StaticResource Bool2Visibility}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="30"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Ellipse Width="20" Height="20" Fill="Green"></Ellipse> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" Foreground="White">√</TextBlock> </Grid> </Grid> </Border> </Window>
来源:https://www.cnblogs.com/3xiaolonglong/p/9781015.html