如何对用户控件中的公开属性使用内置编辑器-遮罩属性编辑器问题 [英] How to use built-in editors for a exposed properties in User Controls - Mask Property Editor Issue

查看:117
本文介绍了如何对用户控件中的公开属性使用内置编辑器-遮罩属性编辑器问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为我的愚蠢问题有一个简单的解决方案,但我今天无法解决.

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

我有一个本身具有MaskedTextBox控件的用户控件.我还公开了它的一些属性供用户修改.

I have a User Control that has a MaskedTextBox Control in itself. I have also exposed a few of its properties for the user to modify.

这些属性之一是Mask属性,我希望使用常规的MaskedTextBox控件中的预定义值启动编辑器来公开该属性.

One of these properties is Mask property which I want to expose with the ability of starting an editor with predefined values like in a normal MaskedTextBox control.

因此,我创建了一个公共属性InputMask并进行了所有设置,使其可以正常工作,但是在显示编辑器后,出现一个包含以下错误的错误对话框:

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

对象引用未设置为对象的实例

Object reference not set to an instance of an object

如果我不使用编辑器并复制蒙版或将其设置为低谷代码,则不会出现问题.

If i don't use editor and copy a mask or set it trough code works without problems.

这是一个代码示例:

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

推荐答案

在通常情况下,注册ui类型编辑器就足够了,您无需执行任何其他操作.但是在MaskPropertyEditor情况下,编辑属性时,编辑器希望属性属于MaskedTextBox并转换

In normal cases it's enough to register ui type editor and you don't need to do anything extra. But in MaskPropertyEditor case, when editing the property, the editor expect the the property belong to a MaskedTextBox and converts ITypeDescriptorContext.Instance to MaskedTextBox and since our editing Mask property belongs to our UserControl which is not a masked text box, a null reference exception will throw.

要解决此问题,您需要创建一个自定义UITypeEditor并覆盖EditValue并编辑私有MaskedTextBox字段的Mask属性.为此,我们需要创建一个包含MaskedTextBoxITypeDescriptorContext实例,并将其传递给编辑器的EditValue方法.

To solve the problem, you need to create a custom UITypeEditor and override EditValue and edit Mask property of the private MaskedTextBox field. To do so, we need to create an instance of ITypeDescriptorContext containing the MaskedTextBox and pass it to EditValue method of the editor.

这里是实现.

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实现

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

这篇关于如何对用户控件中的公开属性使用内置编辑器-遮罩属性编辑器问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆