How to use built-in editors for public properties in User Controls - Mask mask property editor

I think there is a simple solution for my stupid question, but I just can't solve it today.

I have a user control that has a control MaskedTextBoxon its own. I also set a few of my properties for user change.

One of these properties is a property Maskthat I want to open with the ability to start the editor with predefined values, for example, in a regular MaskedTextBox control.

So, I created the public property InputMask and configured everything so that it can work, but after showing the editor I get a dialog box with an error that contains this error:

Object reference not set to object instance

If I do not use the editor and copy the mask or install it, the code works without problems.

Here is a sample 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; }
}
+3
source share
1 answer

In normal cases, it is enough to register an editor like ui, and you do not need to do anything. But in the case MaskPropertyEditorwhen editing a property, the editor expects that the property belongs MaskedTextBoxand converts ITypeDescriptorContext.Instanceto MaskedTextBox, and since our edited property Maskbelongs to ours UserControl, which is not a hidden text field, it throws a null reference exception.

, UITypeEditor EditValue Mask MaskedTextBox. ITypeDescriptorContext, MaskedTextBox, EditValue .

.

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

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 Implementation

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

All Articles