C# 如何为用户控件中的公开属性使用内置编辑器-掩码属性编辑器问题
我想我这个愚蠢的问题有一个简单的解决办法,但我今天就是解决不了 我有一个用户控件,它本身有一个C# 如何为用户控件中的公开属性使用内置编辑器-掩码属性编辑器问题,c#,winforms,user-controls,windows-forms-designer,maskedtextbox,C#,Winforms,User Controls,Windows Forms Designer,Maskedtextbox,我想我这个愚蠢的问题有一个简单的解决办法,但我今天就是解决不了 我有一个用户控件,它本身有一个MaskedTextBox控件。我还公开了它的一些属性供用户修改 其中一个属性是Mask属性,我想公开它,使它能够像在普通MaskedTextBox控件中一样使用预定义值启动编辑器 因此,我创建了一个公共属性InputMask,并对所有内容进行了设置,使其能够工作,但在显示编辑器后,我得到一个错误对话框,其中包含以下错误: 对象引用未设置为对象的实例 如果我不使用编辑器,复制一个掩码,或者通过代码设置它
MaskedTextBox
控件。我还公开了它的一些属性供用户修改
其中一个属性是Mask
属性,我想公开它,使它能够像在普通MaskedTextBox控件中一样使用预定义值启动编辑器
因此,我创建了一个公共属性InputMask,并对所有内容进行了设置,使其能够工作,但在显示编辑器后,我得到一个错误对话框,其中包含以下错误:
对象引用未设置为对象的实例
如果我不使用编辑器,复制一个掩码,或者通过代码设置它,代码就可以正常工作
下面是一个代码示例:
...
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
并转换为MaskedTextBox
,并且由于编辑Mask
属性属于我们的UserControl
,而不是一个屏蔽文本框,将引发空引用异常
要解决此问题,您需要创建一个自定义的UITypeEditor
并重写私有MaskedTextBox
字段的EditValue
和编辑Mask
属性。为此,我们需要创建一个包含MaskedTextBox
的ITypeDescriptorContext
实例,并将其传递给编辑器的EditValue
方法
下面是实现
用户控制
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);
}
}
在这种情况下就没那么简单了。在正常情况下,注册ui类型编辑器就足够了,您不需要做任何额外的事情。但是在
MaskPropertyEditor
情况下,编辑属性时,编辑器希望属性属于MaskedTextBox
。因此,您应该准确地编辑MaskedTextBox
的Mask
属性。非常感谢。它工作得很好。我更喜欢Photoshop(10年以上的设计师)而不是C#开发者,但多亏了你几次的帮助,我为windows窗体应用程序设计并实现了一个漂亮的UI。非常感谢。