4

実行時にオブジェクトのプロパティに EditorAttribute (Editor) を追加する方法は?

私はMy.Settings.ExcludeFiles、設定デザイナーによって として作成されたを持っていますPublic Property ExcludedFiles() As Global.System.Collections.Specialized.StringCollection。プロパティ グリッドを介して編集する場合ExcludedFiles、"String Collection Editor" は "Constructor on type 'System.String' not found" 実行時例外を生成します。

プロパティの属性はExcludeFiles、次に設定を変更したときに上書きされるため、変更できません。したがって、実行時に Editor/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)))

この属性を追加する必要があるのは、アプリケーションの初期化など、1 回だけです。

方法 2

より柔軟に。以下の Nicolas Cadilhac の回答を、実行時に (動的に) Editor / EditorAttribute をオブジェクトのプロパティに追加する で参照してください。派生した CustomTypeDescriptor および TypeDescriptionProvider クラスを使用します。アプリケーションの初期化など、プロバイダーを追加する必要があるのは 1 回だけです。

4

3 に答える 3

6

最初の回答をした後、私がコメントした 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 を使ってより複雑なことを行う必要がある場合に、優れたテクニックを提供しています。

于 2010-01-11T20:26:15.817 に答える
1

はい、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 タイプではなく、String タイプで機能するエディターです。実際に必要なのは、.Net フレームワークのプライベート StringCollectionEditor です。それでは、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-11T19:24:07.033 に答える
0

できません。属性はコンパイル時にのみ定義できます (もちろん動的に型を生成しない限り)

于 2010-01-11T17:40:25.107 に答える