Подтвердить что ты не робот

Использование правил проверки WPF и отключение кнопки "Сохранить"

У меня есть страница, где несколько текстовых полей не могут быть пустыми, прежде чем нажать кнопку "Сохранить".

<TextBox...

                <TextBox.Text>
                    <Binding Path ="LastName" UpdateSourceTrigger="PropertyChanged">

                        <Binding.ValidationRules>
                            <local:StringRequiredValidationRule />
                        </Binding.ValidationRules>                              
                    </Binding>
                </TextBox.Text>

Мое правило работает. У меня есть красная рамка вокруг моего текстового поля, пока я не введу значение. Поэтому теперь я хочу добавить это правило проверки в другие текстовые поля.

Теперь, как отключить кнопку "Сохранить", пока страница не будет иметь ошибок? Я не знаю, что проверить, есть ли ошибки проверки.

4b9b3361

Ответ 2

В коде для представления вы можете подключить Validation.ErrorEvent так:

this.AddHandler(Validation.ErrorEvent,new RoutedEventHandler(OnErrorEvent)); 

И затем

private int errorCount;
private void OnErrorEvent(object sender, RoutedEventArgs e)
{
    var validationEventArgs = e as ValidationErrorEventArgs;
    if (validationEventArgs  == null)
        throw new Exception("Unexpected event args");
    switch(validationEventArgs.Action)
    {
        case ValidationErrorEventAction.Added:
            {
                errorCount++; break;
            }
        case ValidationErrorEventAction.Removed:
            {
                errorCount--; break;
            }
        default:
            {
                throw new Exception("Unknown action");
            }
    }
    Save.IsEnabled = errorCount == 0;
}

Это делает предположение, что вы получите уведомление об удалении (что не произойдет, если вы удалите оскорбительный элемент, пока он недействителен).

Ответ 4

int count = 0;

private void LayoutRoot_BindingValidationError(object sender, ValidationErrorEventArgs e)
{
    if (e.Action == ValidationErrorEventAction.Added)
    {
        button1.IsEnabled = false;
        count++;
    }
    if (e.Action == ValidationErrorEventAction.Removed)
    {                
        count--;
        if (count == 0) button1.IsEnabled = true;
    }
}

Ответ 5

Вот вспомогательный метод, который отслеживает ошибки проверки на объектах зависимостей (и всех его дочерних элементах) и вызывает делегат для уведомления об изменении. Он также отслеживает удаление детей с ошибками проверки.

 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);
        } 

Ответ 6

вот оно вам нужно проверить свойство управления HasError из кода behaind

и сделайте этот код в кнопке сохранения нажмите

 BindingExpression bexp = this.TextBox1.GetBindingExpression(TextBox.TextProperty);
bexp.UpdateSource(); // this to refresh the binding and see if any error exist 
bool hasError = bexp.HasError;  // this is boolean property indique if there is error 

MessageBox.Show(hasError.ToString());

Ответ 7

просто наследует ваш ViewModel из System.ComponentModel.IDataErrorInfo для проверки и из кнопки INotifyPropertyChanged для уведомления

Сделать свойство:

    public bool IsValid
    {
        get
        {
            if (this.FloorPlanName.IsEmpty())
                return false;
            return true;
        }
    }

в xaml, подключите его к кнопке

<Button Margin="4,0,0,0" Style="{StaticResource McVMStdButton_Ok}" Click="btnDialogOk_Click" IsEnabled="{Binding IsValid}"/>

в переопределении IDataErrorInfo, уведомить btutton

public string this[string columnName]{
        get
        {
            switch (columnName)
            {
                case "FloorPlanName":
                    if (this.FloorPlanName.IsEmpty())
                    {
                        OnPropertyChanged("IsValid");
                        return "Floor plan name cant be empty";
                    }
                    break;
            }
        }
}

Ответ 8

Я пробовал несколько решений, указанных выше; однако никто из них не работал у меня.

Моя простая проблема

У меня есть простое окно ввода, которое запрашивает URI от пользователя, если значение TextBox не является допустимым Uri, тогда кнопка Okay должна быть отключена.

Мое простое решение

Вот что сработало для меня:

CommandBindings.Add(new CommandBinding(AppCommands.Okay,
            (sender, args) => DialogResult = true,
            (sender, args) => args.CanExecute = !(bool) _uriTextBoxControl.GetValue(Validation.HasErrorProperty)));

Ответ 9

Поскольку это все еще отсутствует, вот адаптация ответа Разработчика в случае, если ссылка когда-либо исчезнет:

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/С#:

private int _numberOfValidationErrors;
public bool HasNoValidationErrors => _numberOfValidationErrors = 0;

private void handleValidationError(object sender, ValidationErrorEventArgs e)
{
    if (e.Action == ValidationErrorEventAction.Added)
        _numberOfValidationErrors++;
    else
        _numberOfValidationErrors--;
}