2010-02-25 21 views
1

Je dois à nouveau l'aide en vous, cette fois je lutte avec covariance, contravariance, les délégués et une idée simple sauter ...Covariance, Contravariance et délégué Problème

Je veux mettre en œuvre un attribut pour nos BusinessObject-propriétés cela prend un délégué et les paramètres nécessaires pour celui-là, de sorte que je puisse travailler avec la réflexion, lire l'attribut et effectuer une validation sur la valeur de la propriété. La raison derrière cela est que nous utilisons Windows.Forms avec DataBinding et que nous devons définir la méthode de mise à jour de DataBinding sur OnPropertyChanged pour obtenir une actualisation correcte de l'interface graphique. Nous avons cependant besoin d'un moyen de réagir dans les événements de validation des contrôles pour valider la propriété correctement, pour voir si l'utilisateur peut effectivement par ex. enregistrer l'objet. Mais l'événement de validation du contrôle se produit uniquement après avoir écrit la valeur à la propriété. Avoir une validation dans le setter de la propriété provoquerait un crash et nous ne pourrions pas fournir à l'utilisateur des informations exactes ce qui est faux à moins d'implémenter la validation une seconde fois (ou de l'extraire d'une méthode appelée depuis le setter).

Pour garder ce plus élégant et propre, je pensais que l'un des éléments suivants serait agréable d'avoir:

[PropertyValidator(ValidationHelper.ValidateString, new StringValidatorArgs(true, 3, 15))] 

De cette façon, je pourrais itérer par réflexion sur toutes les propriétés, effectuer toutes les validations que nous les voulons et définir un PropertyValidator-Attribute avec la méthode correcte. Mais j'ai un peu joué avec l'idée et je n'arrive pas à la faire fonctionner, voici ce que j'ai, peut-être que vous avez une idée sur la façon de réaliser cela.

public delegate bool Validator(object validatee, ValidatorArgs v); 

public class ValidatorArgs 
{ 
} 

public class StringValidatorArgs : ValidatorArgs 
{ 
    public StringValidatorArgs(bool nullCheck, int minLength, int maxLength) 
    { 
     this.NullCheck = nullCheck; 
     this.MinLength = minLength; 
     this.MaxLength = maxLength; 
    } 

    public bool NullCheck { get; set; } 
    public int MinLength { get; set; } 
    public int MaxLength { get; set; } 
} 

public class MyClass 
{ 
    [PropertyValidator(ValidationHelper.ValidateString, new StringValidatorArgs(true, 3, 15))] 
    public string MyString { get; set; } 
} 

public static class ValidationHelper 
{ 
    public static bool ValidateString(object validatee, StringValidatorArgs v) 
    { 
     return true; 
    } 
} 

[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = true)] 
public class PropertyValidatorAttribute 
    : Attribute 
{ 
    #region Constructor 

    private PropertyValidatorAttribute() 
    { 
    } 

    public PropertyValidatorAttribute(Validator validator, ValidatorArgs args) 
    { 
     this.Validator = validator; 
     this.Args = args; 
    } 

    #endregion 

    #region Properties 

    public Validator Validator 
    { 
     get; 
     private set; 
    } 

    public ValidatorArgs Args 
    { 
     get; 
     private set; 
    } 

    #endregion 
} 

Tous les conseils bienvenus ...

Répondre

2

Qu'en est mise en œuvre IDataErrorInfo de fournir des informations de validation de votre objet, au lieu de (je suppose) lancer une exception du poseur de mauvaises données? La plupart des contrôles Windows Forms sont avertis par IDataErrorInfo et fournissent des informations de validation d'interface utilisateur correspondantes par propriété ou par objet.