Using WPF Validation rules and the disabling of a 'Save' button

前端 未结 10 2012
眼角桃花
眼角桃花 2020-11-28 09:54

I have a page where a few textboxes cannot be empty before clicking a Save button.


                            


        
相关标签:
10条回答
  • 2020-11-28 10:33

    Here is a helper method which tracks validation errors on the dependency objects (and all its children) and calls delegate to notify about the change. It also tracks removal of the children with validation errors.

     public static void AddErrorHandler(DependencyObject element, Action<bool> setHasValidationErrors)
            {
                var errors = new List<Tuple<object, ValidationError>>();
    
                RoutedEventHandler sourceUnloaded = null;
    
                sourceUnloaded = (sender, args) =>
                    {
                        if (sender is FrameworkElement)
                            ((FrameworkElement) sender).Unloaded -= sourceUnloaded;
                        else
                            ((FrameworkContentElement) sender).Unloaded -= sourceUnloaded;
    
                        foreach (var error in errors.Where(err => err.Item1 == sender).ToArray())
                            errors.Remove(error);
    
                        setHasValidationErrors(errors.Any());
                    };
    
                EventHandler<ValidationErrorEventArgs> errorHandler = (_, args) =>
                    {
                        if (args.Action == ValidationErrorEventAction.Added)
                        {
                            errors.Add(new Tuple<object, ValidationError>(args.OriginalSource, args.Error));
    
                            if (args.OriginalSource is FrameworkElement)
                                ((FrameworkElement)args.OriginalSource).Unloaded += sourceUnloaded;
                            else if (args.OriginalSource is FrameworkContentElement)
                                ((FrameworkContentElement)args.OriginalSource).Unloaded += sourceUnloaded;
                        }
                        else
                        {
                            var error = errors
                                .FirstOrDefault(err => err.Item1 == args.OriginalSource && err.Item2 == args.Error);
    
                            if (error != null) 
                                errors.Remove(error);
                        }
    
                        setHasValidationErrors(errors.Any());
                    };
    
    
                System.Windows.Controls.Validation.AddErrorHandler(element, errorHandler);
            } 
    
    0 讨论(0)
  • 2020-11-28 10:33

    Because it's still missing, here is an adaption of Developer's answer in case the link ever goes away:

    XAML:

    <TextBox.Text Validation.Error="handleValidationError">
        <Binding Path ="LastName" 
                 UpdateSourceTrigger="PropertyChanged"
                 NotifyOnValidationError="True">
            <Binding.ValidationRules>
                <local:StringRequiredValidationRule />
            </Binding.ValidationRules>                              
        </Binding>
    </TextBox.Text>
    <Button IsEnabled="{Binding HasNoValidationErrors}"/>
    

    CodeBehind/C#:

    private int _numberOfValidationErrors;
    public bool HasNoValidationErrors => _numberOfValidationErrors = 0;
    
    private void handleValidationError(object sender, ValidationErrorEventArgs e)
    {
        if (e.Action == ValidationErrorEventAction.Added)
            _numberOfValidationErrors++;
        else
            _numberOfValidationErrors--;
    }
    
    0 讨论(0)
  • 2020-11-28 10:34

    This website has the code you're looking for: https://www.wpfsharp.com/2012/02/03/how-to-disable-a-button-on-textbox-validationerrors-in-wpf/

    For posterity the button code should look like this if you are using a ValidationRule override on the input fields:

    <Button Content="<NameThisButton>" Click="<MethodToCallOnClick>" >
                    <Button.Style>
                        <Style TargetType="{x:Type Button}">
                            <Setter Property="IsEnabled" Value="false" />
                            <Style.Triggers>
                                <MultiDataTrigger>
                                    <MultiDataTrigger.Conditions>                                    
                                        <Condition Binding="{Binding ElementName=<TextBoxName>, Path=(Validation.HasError)}" Value="false" />
                                        <Condition Binding="{Binding ElementName=<TextBoxName>, Path=(Validation.HasError)}" Value="false" />
                                    </MultiDataTrigger.Conditions>
                                    <Setter Property="IsEnabled" Value="true" />
                                </MultiDataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Button.Style>
                </Button>
    
    0 讨论(0)
  • 2020-11-28 10:38

    Here is the complete sample what you need.

    http://codeblitz.wordpress.com/2009/05/08/wpf-validation-made-easy-with-idataerrorinfo/

    https://skydrive.live.com/?cid=2c6600f1c1d5e3be&id=2C6600F1C1D5E3BE%21203

    enter image description here

    0 讨论(0)
提交回复
热议问题