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>

 

posted @ 2024-08-27 13:31  【君莫笑】  阅读(24)  评论(0编辑  收藏  举报