3

Je pense qu'il existe une solution simple à ma question stupide, mais je ne peux pas la résoudre aujourd'hui.Comment utiliser les éditeurs intégrés pour des propriétés exposées dans Contrôles utilisateur - Editeur de propriétés de masque Problème

J'ai un contrôle utilisateur qui a un contrôle MaskedTextBox en lui-même. J'ai également exposé quelques-unes de ses propriétés pour que l'utilisateur puisse les modifier. Une de ces propriétés est Mask propriété que je veux exposer avec la possibilité de démarrer un éditeur avec des valeurs prédéfinies comme dans un contrôle MaskedTextBox normal.

Je créé une propriété publique InputMask et tout mettre en place pour qu'il puisse fonctionner, mais après avoir montré l'éditeur, je reçois un message d'erreur qui contient cette erreur:

Object reference not set to an instance of an object

Si je ne pas utiliser l'éditeur et copier un masque ou le définir à travers le code fonctionne sans problèmes.

Voici un exemple de code:

... 
MaskedTextBox maskedtextbox; 
myUserControl() 
{ 
    ... 
    maskedtextbox = new MaskedTextBox(){ 
     some stuff... 
    }; 
} 

[DefaultValue("")] 
[Editor("System.Windows.Forms.Design.MaskPropertyEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] 
[Localizable(true)] 
[MergableProperty(false)] 
[RefreshProperties(RefreshProperties.Repaint)] 
public string InputMask 
{ 
    get { return this.maskedtextbox.Mask; } 
    set { this.maskedtextbox.Mask = value; } 
} 
+0

Ce n'est pas simple dans ce Cas. Dans les cas normaux, il suffit d'enregistrer l'éditeur de type ui et vous n'avez rien à faire de plus. Mais dans le cas de 'MaskPropertyEditor', lors de la modification de la propriété, l'éditeur s'attend à ce que la propriété appartienne à' MaskedTextBox'. Vous devriez donc éditer exactement la propriété 'Mask' du' MaskedTextBox'. –

Répondre

2

Dans les cas normaux, il suffit de vous inscrire ui éditeur de type et vous n'avez pas besoin de faire quoi que ce soit de plus. Mais dans MaskPropertyEditor, lors de la modification de la propriété, l'éditeur s'attend à ce que la propriété appartienne à MaskedTextBox et convertit ITypeDescriptorContext.Instance en MaskedTextBox et puisque notre propriété d'édition Mask appartient à notre UserControl qui n'est pas une boîte de texte masquée, une exception de référence null sera lancée.

Pour résoudre le problème, vous devez créer une coutume UITypeEditor et passer outre EditValue et modifier Mask propriété du champ MaskedTextBox privé. Pour ce faire, nous devons créer une instance de ITypeDescriptorContext contenant le MaskedTextBox et la passer à la méthode EditValue de l'éditeur.

Voici les implémentations.

UserControl

public partial class UserControl1 : UserControl 
{ 
    MaskedTextBox maskedTextBox; 
    public UserControl1() 
    { 
     InitializeComponent(); 
     maskedTextBox = new MaskedTextBox(); 
    } 

    [Editor(typeof(MaskEditor), typeof(UITypeEditor))] 
    public string Mask 
    { 
     get { return maskedTextBox.Mask; } 
     set { maskedTextBox.Mask = value; } 
    } 
} 

Editeur

public class MaskEditor : UITypeEditor 
{ 
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) 
    { 
     return UITypeEditorEditStyle.Modal; 
    } 
    public override object EditValue(ITypeDescriptorContext context, 
            IServiceProvider provider, object value) 
    { 
     var field = context.Instance.GetType().GetField("maskedTextBox", 
         System.Reflection.BindingFlags.NonPublic | 
         System.Reflection.BindingFlags.Instance); 
     var maskedTextBox = (MaskedTextBox)field.GetValue(context.Instance); 
     var maskProperty = TypeDescriptor.GetProperties(maskedTextBox)["Mask"]; 
     var tdc = new TypeDescriptionContext(maskedTextBox, maskProperty); 
     var editor = (UITypeEditor)maskProperty.GetEditor(typeof(UITypeEditor)); 
     return editor.EditValue(tdc, provider, value); 
    } 
} 

ITypeDescriptionContext mise en œuvre

public class TypeDescriptionContext : ITypeDescriptorContext 
{ 
    private Control editingObject; 
    private PropertyDescriptor editingProperty; 
    public TypeDescriptionContext(Control obj, PropertyDescriptor property) 
    { 
     editingObject = obj; 
     editingProperty = property; 
    } 
    public IContainer Container 
    { 
     get { return editingObject.Container; } 
    } 
    public object Instance 
    { 
     get { return editingObject; } 
    } 
    public void OnComponentChanged() 
    { 
    } 
    public bool OnComponentChanging() 
    { 
     return true; 
    } 
    public PropertyDescriptor PropertyDescriptor 
    { 
     get { return editingProperty; } 
    } 
    public object GetService(Type serviceType) 
    { 
     return editingObject.Site.GetService(serviceType); 
    } 
} 
+0

Merci beaucoup. Cela fonctionne très bien. Im plus d'une personne de Photoshop (Designer sur 10 ans) qu'un développeur C# mais grâce à vous m'aider à quelques reprises, j'ai conçu et mis en œuvre une interface utilisateur sympa pour une application Windows Forms. Je vous remercie. – Dino