如何在运行时将EditorAttribute (编辑器)添加到对象的属性?
我有My.Settings.ExcludeFiles,它是由设置设计器作为Public Property ExcludedFiles() As Global.System.Collections.Specialized.StringCollection创建的。当通过属性网格编辑ExcludedFiles时,"String“将生成一个”构造类型'System.String‘上的构造函数“运行时异常。
我不能更改ExcludeFiles属性的属性,因为它们将在下一次进行任何设置更改时被覆盖。因此,我必须在运行时附加/添加编辑器/EditorAttribute。
我想要做的是在运行时添加StringCollectionEditor,如下所示为设计时属性。
<Editor(GetType(StringCollectionEditor), GetType(UITypeEditor))> _解决方案
方法1
TypeDescriptor.AddAttributes( _
GetType(Specialized.StringCollection), _
New EditorAttribute( _
"System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", _
GetType(System.Drawing.Design.UITypeEditor)))您只需添加一次此属性,例如应用程序初始化。
方法2
更灵活。参见尼古拉斯·卡迪尔哈克( Nicolas )在在运行时(动态)向对象的属性添加编辑器/ EditorAttribute的回答。它使用派生的CustomTypeDescriptor和TypeDescriptionProvider类。您只需添加一次提供程序,例如应用程序初始化。
发布于 2010-01-11 20:26:15
在给出我的第一个答案后,我想起了Marc给出的另一个解决方案,我甚至评论过。信不信由你,只需调用TypeDescriptor.AddAttributes()即可。
这里是:如何为封闭源类型的所有属性注入自定义UITypeEditor?。
就你的情况而言,它提供:
TypeDescriptor.AddAttributes(
typeof(StringCollection),
new EditorAttribute("System.Windows.Forms.Design.StringCollectionEditor,
System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
typeof(UITypeEditor)))所以也许你应该取消检查我以前的答案,并确认这个答案是解决方案(尽管所有的功劳都归于Marc)。但是,当您需要使用TypeDescriptor做更复杂的事情时,我上一篇文章仍然为您提供了一种很好的技术。
发布于 2010-01-11 19:24:07
是的,可以动态地更改TypeDescriptor,以便返回所需的UITypeEditor。在这个文章中解释了这一点。但是请注意,它将为该类型的所有属性添加它。
我从这里抓起了代码,并对其进行了粗略的修改,如下所示:
private class StringCollectionTypeDescriptor : CustomTypeDescriptor
{
private Type _objectType;
private StringCollectionTypeDescriptionProvider _provider;
public StringCollectionTypeDescriptor(
StringCollectionTypeDescriptionProvider provider,
ICustomTypeDescriptor descriptor, Type objectType)
:
base(descriptor)
{
if (provider == null) throw new ArgumentNullException("provider");
if (descriptor == null)
throw new ArgumentNullException("descriptor");
if (objectType == null)
throw new ArgumentNullException("objectType");
_objectType = objectType;
_provider = provider;
}
/* Here is your customization */
public override object GetEditor(Type editorBaseType)
{
return new MultilineStringEditor();
}
}
public class StringCollectionTypeDescriptionProvider : TypeDescriptionProvider
{
private TypeDescriptionProvider _baseProvider;
public StringCollectionTypeDescriptionProvider(Type t)
{
_baseProvider = TypeDescriptor.GetProvider(t);
}
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
return new StringCollectionTypeDescriptor(this, _baseProvider.GetTypeDescriptor(objectType, instance), objectType);
}
}然后你注册你的提供者:
TypeDescriptor.AddProvider(new StringCollectionTypeDescriptionProvider
(typeof(System.Collections.Specialized.StringCollection)),
typeof(System.Collections.Specialized.StringCollection));这很好,只是它会让您发现另一个问题: MultilineStringEditor是一个处理字符串类型的编辑器,而不是StringCollection类型。您实际上需要的是.Net框架中的私有.Net。因此,让我们将GetEditor替换为:
public override object GetEditor(Type editorBaseType)
{
Type t = Type.GetType("System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
return TypeDescriptor.CreateInstance(null, t, new Type[] { typeof(Type) }, new object[] { typeof(string) });
}我希望这能帮到你。
发布于 2010-01-11 17:40:25
属性只能在编译时定义(当然,除非动态生成类型)
https://stackoverflow.com/questions/2043579
复制相似问题