none
DataAnnotations en proyecto de WPF con MVVM RRS feed

  • Pregunta

  • Estoy tratando de implementar validaciones en mi proyecto WPF en el que estoy usando MVVM

    en mi ViewModel (AsignaFacturasVM) tengo algunas propiedades, entre ellas Operación, que estoy declarando así:

    #region Operacion
    private string _operacion;
    [Required(ErrorMessage = "Debe ingresar el identificador de la operación bancaria")]
    [MaxLength(100, ErrorMessage = "La Operación debe ser de longitud máxima 100")]
    [MinLength(1, ErrorMessage = "La Operación debe ser de longitud mínima 1")]
    [RegularExpression(@"^[A-Z0-9_]{10,50}",
            ErrorMessage = "Solo se permiten letras, números y _")]
    public string Operacion
    {
        set
        {
            _operacion = value;
            OnPropertyChanged("Operacion");
            OnPropertyChanged("IsEnabledButton");
        }
        get { return _operacion; }
    }
    #endregion

    Y luego en mi Vista, este dato se captura en:

    <TextBox Text="{Binding Operacion, Mode=TwoWay, Source={StaticResource asignaFacturasVM},
        ValidatesOnDataErrors=True, ValidatesOnExceptions=True, ValidatesOnNotifyDataErrors=True, NotifyOnTargetUpdated=True,
        NotifyOnSourceUpdated=True, NotifyOnValidationError=True}" Margin="5,10,10,5" 
                GotFocus="TextBox_GotFocus" ToolTipService.ToolTip="Identificador del pago (Folio del depósito, #Cheque, #Transferencia..)"
                HorizontalAlignment="Left" VerticalAlignment="Center" Width="150" MaxLength="100"/>
    
    pero cuando entro a capturar este dato, la caja de TextBox, nunca me marca error, sin importar lo que capture, qué me falta?


    cyndyrdz

    miércoles, 22 de agosto de 2018 21:28

Respuestas

  • Hola Cynthia.

    Echale un vistazo a ete post que lo explica:

    http://danielvistisen.com/validate-using-attributes-in-mvvm/

    En wpf la validación no ha sido el fuerte, ya que hay muchas formas pero ninguna muy sencilla, de modo que siempre tienes que implementar alguna interface.



    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    viernes, 24 de agosto de 2018 7:42

Todas las respuestas

  • Hola Cynthia.

    Echale un vistazo a ete post que lo explica:

    http://danielvistisen.com/validate-using-attributes-in-mvvm/

    En wpf la validación no ha sido el fuerte, ya que hay muchas formas pero ninguna muy sencilla, de modo que siempre tienes que implementar alguna interface.



    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    viernes, 24 de agosto de 2018 7:42
  • He encontrado una clase que usaba como base en los viewmodels, te la pongo aquí para que la reuses como quieras:

    En principio heredando de ella se implementa notificación de propiedades y errores basados en atributos

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    
    /// <summary>
    /// Nombre de espacios con clases comunes base para usar en los proyectos
    /// </summary>
    namespace Dgzornoza.Toolkit.Xaml.Common
    {
        /// <summary>
        /// Clase base comun para implementar notificaciones de propiedades y verificacion de propiedades
        /// </summary>
        public abstract class CommonBase : INotifyPropertyChanged, IDataErrorInfo
        {
    
            #region [Helper Debugger]
    
            /// <summary>
            /// Propiedad para verificar que una propiedad existe como publica, de forma que
            /// ayude a encontrar errores en procesos de refactorizacion u otros.
            /// Esta propiedad solo esta disponible en entornos de depuracion.
            /// </summary>
            /// <param name="propertyName">Nombre de la propiedad a validar</param>
            [Conditional("DEBUG")]
            [DebuggerStepThrough]
            public void VerifyPropertyName(string _propertyName)
            {
                // verificar que el nombre de la propiedad coincide con una propiedad publica
                if (this.GetType().GetProperties(System.Reflection.BindingFlags.Public).FirstOrDefault(
                    (property) => property.Name == _propertyName) == null)
                {
                    string msg = "Error: Nombre de propiedad invalida: " + _propertyName;
    
                    // dependiendo del valor de la propiedad 'ThrowOnInvalidPropertyName' se realiza una accion
                    if (this.ThrowOnInvalidPropertyName)
                        throw new Exception(msg);
                    else
                        Debug.WriteLine(msg);
                }
            }
    
            /// <summary>
            /// propiedad para determiar si se debe lanzar una excepcion cuando una propiedad no existe
            /// o si se debe usar un Debug.Fail()
            /// Cuando un nombre de propiedad no válida se pasa al metodo VerifyPropertyName.
            /// El valor predeterminado es falso, pero las subclases utilizadas por las pruebas unitarias pueden
            /// reemplazar esta propiedad para devolver true.
            /// </summary>
            protected virtual bool ThrowOnInvalidPropertyName { get; private set; }
    
            #endregion [Helper Debugger]
    
    
            #region [INotifyPropertyChanged]
    
            /// <summary>
            /// declarar el evento ocurrido cuando una propiedad de este objeto tiene un nuevo valor
            /// </summary>
            public event PropertyChangedEventHandler PropertyChanged;
    
            /// <summary>
            /// Definicion del evento PropertyChanged que sera llamado cuando un valor de una propiedad sea modificado
            /// </summary>
            /// <param name="_propertyName">El nombre de la propiedad con el nuevo valor</param>
            protected virtual void OnPropertyChanged(string _propertyName)
            {
                // verificar que la propiedad existe
                this.VerifyPropertyName(_propertyName);
    
                // añadir el manejador del evento
                PropertyChangedEventHandler handler = PropertyChanged;
                // si existe el manejador del evento, se invoca
                if (handler != null) handler(this, new PropertyChangedEventArgs(_propertyName));
            }
    
            #endregion [INotifyPropertyChanged]
    
    
            #region [IDataErrorInfo]
    
            /// <summary>
            /// Propiedad de la interface 'IDataErrorInfo' para obtener un mensage de error global al objeto para mantener la integridad
            /// (no usado en esta arquitectura actualmente)
            /// </summary>
            public string Error
            {
                get
                {
                    return null;
                }
            }
    
            /// <summary>
            /// Obtener un mensaje de error para la propiedad indizada establecida
            /// </summary>
            /// <param name="_property">Nombre de la propiedad que seran comprobados los atributos de DataAnnotations para chequear posibles errores</param>
            /// <returns></returns>
            public string this[string _property]
            {
                get { return this.OnValidate(_property); }
            }
    
            /// <summary>
            /// Validar la la propiedad de la instancia actual usando DataAnnotations
            /// </summary>
            /// <param name="_propertyName">Nombre de la propiedad a validar</param>
            /// <returns>Si existe error, se retorna la cadena con el error, si NO hay error, una cadena vacia</returns>
            protected virtual string OnValidate(string _propertyName)
            {
                // verificar nombre de la propiedad
                if (string.IsNullOrEmpty(_propertyName))
                    throw new ArgumentException("Nombre de propiedad a validar invalida", _propertyName);
    
                // inicialmente no existe error
                string result = string.Empty;
    
                // obtener el valor de la propiedad
                object value = this.GetType().GetProperty(_propertyName).GetValue(this, null);
    
                // crear lista para resultados de validacion
                List<ValidationResult> validationResult = new List<ValidationResult>(1);
                // contexto de validacion para validar la propiedad
                ValidationContext validationContext = new ValidationContext(this, null, null) { MemberName = _propertyName };
                // intentar validar la propiedad
                bool isValid = Validator.TryValidateProperty(value, validationContext, validationResult);
    
                // si no es valida, se obtiene el error
                if (!isValid) result = validationResult.First().ErrorMessage;   
    
                // retornar el posible error
                return result;
            }
    
    
            #endregion [IDataErrorInfo]
        }
    
    }


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/


    viernes, 24 de agosto de 2018 7:46
  • David_González muchas gracias por el apoyo, reviso despacio todo lo que me sugieres. Saludos

    cyndyrdz

    viernes, 24 de agosto de 2018 13:16