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