在运行时(动态)添加编辑器 / editorAttribute到对象的属性
-
19-09-2019 - |
题
如何在运行时将EditorAttribute(编辑器)添加到对象的属性中?
我有 My.Settings.ExcludeFiles
, ,这是由设置设计师创建的 Public Property ExcludedFiles() As Global.System.Collections.Specialized.StringCollection
. 。编辑时 ExcludedFiles
通过属性网格,“字符串集合编辑器”在type'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 Cadilhac答案 在运行时(动态)添加编辑器 / editorAttribute到对象的属性. 。它使用派生的CustomTypedScriptor和TypeDescriptionProvider类。您只需要添加一次提供商,例如应用程序初始化。
解决方案
在给您我的第一个答案之后,我想起了Marc Gravell提供的另一种解决方案,我什至评论了。信不信由你,您只需要致电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做更多复杂的事情时,我以前的帖子仍然为您提供了一项很好的技术。
其他提示
你不能。属性只能在编译时间定义(除非您当然动态生成类型)
是的,可以动态更改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));
这效果很好,除了它会让您发现自己还有另一个问题:MultineStringeditor是与字符串类型一起使用的编辑器,而不是使用StringCollection类型。您实际上需要的是.NET框架中的私有字符串collectioneditor。因此,让我们替换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) });
}
我希望这有帮助。