如何在运行时将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) });
}

我希望这有帮助。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top