런타임 (동적)에 편집기 / 편집기 편집자 추가 객체의 속성에 추가
-
19-09-2019 - |
문제
런타임시 객체의 속성에 editorAttribute (편집기)를 추가하는 방법은 무엇입니까?
나는 가지고있다 My.Settings.ExcludeFiles
, 설정 디자이너에 의해 생성됩니다 Public Property ExcludedFiles() As Global.System.Collections.Specialized.StringCollection
. 편집 할 때 ExcludedFiles
속성 그리드를 통해 "String Collection Editor"는 "Type 'System.String'에 대한 생성자를 찾을 수 없음"런타임 예외를 생성합니다.
나는 속성을 변경할 수 없습니다 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)))
응용 프로그램 초기화와 같이이 속성을 한 번만 추가하면됩니다.
방법 #2
더 유연합니다. 아래에서 Nicolas Cadilhac 답변을 참조하십시오 런타임 (동적)에 편집기 / 편집기 편집자 추가 객체의 속성에 추가. 파생 된 Customtypedescriptor 및 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에게 제공되지만). 그러나 내 이전 게시물은 타이드 스크립터로 더 복잡한 작업을 수행해야 할 때 여전히 좋은 기술을 제공합니다.
다른 팁
당신은 할 수 없습니다. 속성은 컴파일 시간에만 정의 할 수 있습니다 (물론 유형을 동적으로 생성하지 않는 한).
예, 원하는 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 Framework의 Private 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) });
}
이게 도움이 되길 바란다.