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

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

问题描述

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

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 并转换 ITypeDescriptorContext.InstanceMaskedTextBox 并且由于我们的编辑 Mask 属性属于我们的 UserControl 这不是蒙面文本框,会抛出空引用异常.

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.

这里是实现.

用户控制

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

可能需要重新加载项目,Visual Studio 才能识别新的 UITypeEditor

The project may need to be reloaded before Visual Studio can recognize the new UITypeEditor

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

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