WPF 数据校验
一、新建NameValidationRule类 public class NameValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { var length = value.ToString().Length; if (length >= 2 && length <= 10) { return new ValidationResult(isValid: true, errorContent: ""); } return new ValidationResult(isValid: false, errorContent: "用户名长度为2-10"); } }
public class MyBindingBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; //protected virtual void OnPropertyChanged(string propertyName) protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")//此处使用特性 { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
public class MyValidationRuleViewModel : MyBindingBase { private string name = "2222222222222"; public string Name { get { return name; } set { name = value; OnPropertyChanged();//OnPropertyChanged(nameof(name),使用特性,去掉括号的值 } } }
<Window.DataContext> <viewModel:MyValidationRuleViewModel /> </Window.DataContext> <Grid> <StackPanel Width="300" Height="200"> <StackPanel Orientation="Horizontal"> <TextBlock Text="姓名:" /> <TextBox x:Name="txtName" Width="120"> <TextBox.Text> <Binding Path="Name" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:NameValidationRule ValidatesOnTargetUpdated="True" /> </Binding.ValidationRules> </Binding> </TextBox.Text> <Validation.ErrorTemplate> <ControlTemplate> <DockPanel> <TextBlock Margin="10,0,0,0" DockPanel.Dock="Right" Foreground="Red" Text="{Binding ElementName=AdornedElementPlaceholder, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}" /> <AdornedElementPlaceholder x:Name="AdornedElementPlaceholder" /> </DockPanel> </ControlTemplate> </Validation.ErrorTemplate> </TextBox> </StackPanel> </StackPanel> <Button Content="Button" HorizontalAlignment="Left" Margin="89,254,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> </Grid>
注: ValidatesOnTargetUpdated="True" 表示默认值也参与校验,为false默认值不参与校验
后台代码: private void Button_Click(object sender, RoutedEventArgs e) { // 获取名称的错误消息 var nameErrorMsg = Validation.GetErrors(txtName)[0].ErrorContent.ToString(); }
案例2:新建NotEmptyValidationRule public class NotEmptyValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { return string.IsNullOrWhiteSpace((value ?? "").ToString()) ? new ValidationResult(false, "Error") : ValidationResult.ValidResult; } }
public class MainViewModel : ViewModelBase , IValidationExceptionHandler { public RelayCommand SaveCommand { get; set; } public MainViewModel() { SaveCommand = new RelayCommand(() => { if (!isValid) { MessageBox.Show("请别乱输入"); return; } }); } private string name; public string Name { get { return name; } set { name = value; RaisePropertyChanged(); } } private bool isValid; public bool IsValid { get { return isValid; } set { isValid = value;RaisePropertyChanged(); } } }
public class ValitationExceptionBeahyior : Behavior<FrameworkElement> { private int _validationExceptioncount = 0; protected override void OnAttached() { base.OnAttached(); this.AssociatedObject.AddHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(OnValidationError)); } private void OnValidationError(object sender, ValidationErrorEventArgs e) { IValidationExceptionHandler handler = null; if (AssociatedObject.DataContext is IValidationExceptionHandler) { handler = this.AssociatedObject.DataContext as IValidationExceptionHandler; } if (handler == null) return; var element = e.OriginalSource as UIElement; if (element == null) return; if (e.Action == ValidationErrorEventAction.Added) { _validationExceptioncount++; } else if(e.Action == ValidationErrorEventAction.Removed) { _validationExceptioncount--; } handler.IsValid = _validationExceptioncount == 0; } protected override void OnDetaching() { base.OnDetaching(); this.AssociatedObject.RemoveHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(OnValidationError)); } }
public interface IValidationExceptionHandler { bool IsValid { get; set; } }
<Window.DataContext>
<viewModel:MainViewModel />
</Window.DataContext>
<i:Interaction.Behaviors> <local2:ValitationExceptionBeahyior /> </i:Interaction.Behaviors> <Grid> <StackPanel> <TextBox Width="200" Height="30"> <TextBox.Text> <Binding NotifyOnValidationError="True" Path="Name" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:NotEmptyValidationRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <Button Command="{Binding SaveCommand}" Content="提交" /> </StackPanel> </Grid>