Pregunta

Tengo una página donde algunos cuadros de texto no pueden estar vacíos antes de hacer clic en el botón Guardar.

<TextBox...

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

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

Mi regla funciona. Tengo un borde rojo alrededor de mi cuadro de texto hasta que ingrese un valor. Así que ahora quiero agregar esta regla de validación a mis otros cuadros de texto.

Ahora, ¿cómo desactivo el botón Guardar hasta que la página no tenga errores? No sé qué verificar para ver si hay algún error de validación.

Otros consejos

En el código de la vista, puedes conectar el Validation.ErrorEvent de esta forma;

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

Y luego

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

Esto supone que se le notificará la eliminación (lo cual no sucederá si elimina el elemento ofensivo mientras no sea válido).

Desea utilizar Validation.HasError propiedad adjunta.

En la misma línea, Josh Smith tiene una lectura interesante en Enlace a (Validation.Errors) [0] sin crear Debug Spew .

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

Aquí hay un método auxiliar que rastrea los errores de validación en los objetos de dependencia (y todos sus hijos) y llama al delegado para notificar el cambio. También rastrea la eliminación de los hijos con errores de validación.

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

esto es debe verificar la propiedad de control HasError desde el código que se muestra a continuación

y haga este código en el botón de guardar, haga clic

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

simplemente hereda su ViewModel de System.ComponentModel.IDataErrorInfo para validar y desde INotifyPropertyChanged para notificar el botón

hacer propiedad:

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

en xaml, conéctalo al botón

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

en las anulaciones de IDataErrorInfo, notifique a 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;
            }
        }
}

He probado varias de las soluciones mencionadas anteriormente; Sin embargo, ninguno de ellos trabajó para mí.

Mi problema simple

Tengo una ventana de entrada simple que solicita un URI al usuario, si el valor TextBox no es un Uri válido, entonces el Ok El botón debería estar desactivado.

Mi solución simple

Esto es lo que funcionó para mí:

CommandBindings.Add(new CommandBinding(AppCommands.Okay,
            (sender, args) => DialogResult = true,
            (sender, args) => args.CanExecute = !(bool) _uriTextBoxControl.GetValue(Validation.HasErrorProperty)));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top