Pregunta

Tengo un control de usuario que contiene un cuadro de texto. Tengo una clase llamada Persona que implementa la interfaz IDataErrorInfo:

class Person : IDataErrorInfo
{
private bool hasErrors = false;
#region IDataErrorInfo Members

        public string Error
        {            
            get 
            {
                string error = null;
                if (hasErrors)
                {
                    error = "xxThe form contains one or more validation errors";
                }
                return error;
            }
        }

        public string this[string columnName]
        {
            get 
            {
                return DoValidation(columnName);
            }
        }
        #endregion
}

Ahora el control de usuario expone un método llamado SetSource a través del cual el código establece el enlace:

public partial class TxtUserControl : UserControl 
    {          
        private Binding _binding;

        public void SetSource(string path,Object source)
        {
            _binding = new Binding(path);
            _binding.Source = source;
            ValidationRule rule;
            rule = new DataErrorValidationRule();
            rule.ValidatesOnTargetUpdated = true;            
            _binding.ValidationRules.Add(rule);
            _binding.ValidatesOnDataErrors = true;
            _binding.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
            _binding.NotifyOnValidationError = true;            
            _binding.ValidatesOnExceptions = true;
            txtNumeric.SetBinding(TextBox.TextProperty, _binding);                
        }
...
}

La ventana WPF que incluye el control del usuario tiene el siguiente código:

public SampleWindow()
    {
        person= new Person();
        person.Age = new Age();
        person.Age.Value = 28;

        numericAdmins.SetSource("Age.Value", person);
    }
    private void btnOk_Click(object sender, RoutedEventArgs e)
    {         

        if(!String.IsNullOrEmpty(person.Error))
        {
            MessageBox.Show("Error: "+person.Error);
        }
    }

Dado este código, el enlace funciona bien, pero la validación nunca se activa. ¿Qué tiene de malo este código?

¿Fue útil?

Solución

Tu clase Age necesitará implementar IDataErrorInfo . No se le pedirá a su clase Person que valide las propiedades de Age .

Si esa no es una opción, escribí un sistema de validación para WPF que es lo suficientemente extensible como para admitir esto. La URL está aquí:

En el ZIP hay un documento de Word que lo describe.

Editar: aquí hay una forma en que age podría implementar IDataErrorInfo sin ser demasiado inteligente:

class Constraint 
{
    public string Message { get; set; }
    public Func<bool> Validate;
    public string Name { get; set; }
}

class Age : IDataErrorInfo
{
    private readonly List<Constraint> _constraints = new List<Constraint>();

    public string this[string columnName]
    {
        get 
        {
            var constraint = _constrains.Where(c => c.Name == columnName).FirstOrDefault();
            if (constraint != null)
            {
                if (!constraint.Validate())
                {
                    return constraint.Message;
                }
            }
            return string.Empty;
        }
    }
}

class Person
{
    private Age _age;

    public Person() 
    {
        _age = new Age(
            new Constraint("Value", "Value must be greater than 28", () => Age > 28);
    }
}

También vea este enlace:

http://www.codeproject.com/KB/cs/DelegateBusinessObjects.aspx

Otros consejos

Otra opción podría ser implementar IDataErrorInfo en la clase Age y crear un evento en él como OnValidationRequested que debería ser capturado por la clase Person. De esta manera, podría validar el campo Edad basado en otras propiedades de la clase Persona.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top