実行時に(動的に)オブジェクトのプロパティに編集 /編集を追加する
-
19-09-2019 - |
質問
実行時にeditorattribute(editor)をオブジェクトのプロパティに追加する方法は?
私は持っている My.Settings.ExcludeFiles
, 、設定デザイナーによって作成されます Public Property ExcludedFiles() As Global.System.Collections.Specialized.StringCollection
. 。編集するとき ExcludedFiles
プロパティグリッドを介して、「String Collection Editor」は、「タイプ「System」のコンストラクター」を生成します。
の属性を変更することはできません ExcludeFiles
プロパティは、次回設定の変更が行われたときに上書きされるためです。したがって、実行時に編集者/編集を添付/追加する必要があります。
私がやりたいのは、追加することです 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の回答を参照してください 実行時に(動的に)オブジェクトのプロパティに編集 /編集を追加する. 。派生したCustomTypedEScriptorとtypedescriptionProviderクラスを使用します。アプリケーションの初期化など、プロバイダーを1回追加する必要があります。
解決
私の最初の答えをあなたに与えた後、私はコメントした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));
これはうまく機能しますが、別の問題があることを発見することを除いて、Multilinestringeditorは、stringCollectionタイプではなく、文字列タイプで動作するエディターです。実際に必要なのは、.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) });
}
これが役立つことを願っています。