public class Person { public string Name { get; set; } } public class PersonTypeDescriptionProvider : TypeDescriptionProvider { public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) { ICustomTypeDescriptor baseDescriptor = base.GetTypeDescriptor(objectType, instance); return new PersonCustomTypeDescriptor(baseDescriptor); } } public class PersonCustomTypeDescriptor : CustomTypeDescriptor { private PropertyDescriptorCollection _properties; public PersonCustomTypeDescriptor(ICustomTypeDescriptor parent) : base(parent) { var properties = new List(TypeDescriptor.GetProperties(typeof(Person))); properties.Add(new MyCustomPropertyDescriptor("Age", typeof(int))); _properties = new PropertyDescriptorCollection(properties.ToArray()); } public override PropertyDescriptorCollection GetProperties() { return _properties; } } public class MyCustomPropertyDescriptor : PropertyDescriptor { public MyCustomPropertyDescriptor(string name, Type type) : base(name, new Attribute[] { }) { PropertyType = type; } public override bool CanResetValue(object component) { return false; } public override object GetValue(object component) { return 0; } public override void ResetValue(object component) { } public override void SetValue(object component, object value) { } public override bool ShouldSerializeValue(object component) { return false; } public override Type PropertyType { get; } public override bool IsReadOnly => false; }
public class MyClass { public int Square(int number) { return number * number; } } public class MyCustomTypeDescriptionProvider : TypeDescriptionProvider { public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) { ICustomTypeDescriptor baseDescriptor = base.GetTypeDescriptor(objectType, instance); return new MyCustomTypeDescriptor(baseDescriptor); } } public class MyCustomTypeDescriptor : CustomTypeDescriptor { public MyCustomTypeDescriptor(ICustomTypeDescriptor parent) : base(parent) { } public override MethodDescriptorCollection GetMethods() { var methods = new ListThis code adds a custom Square method to the MyClass class using the AddProviderTransparent method. The method is defined in the MyCustomTypeDescriptor class, and the provider is added in the MyCustomTypeDescriptionProvider class. The package library for TypeDescriptor is System.ComponentModel.(base.GetMethods().Cast ()); var squareMethod = new MyCustomMethodDescriptor("Square", typeof(int), new[] { typeof(int) }); methods.Add(squareMethod); return new MethodDescriptorCollection(methods.ToArray()); } } public class MyCustomMethodDescriptor : MethodDescriptor { private readonly Type _returnType; private readonly Type[] _parameterTypes; private readonly string _name; public MyCustomMethodDescriptor( string name, Type returnType, Type[] parameterTypes) : base(name, new Attribute[] { }) { _returnType = returnType; _parameterTypes = parameterTypes; _name = name; } public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) { if (obj == null) { return null; } if (!_parameterTypes.SequenceEqual(parameters.Select(p => p.GetType()))) { throw new ArgumentException(); } var method = obj.GetType().GetMethod(_name, _parameterTypes); return method.Invoke(obj, parameters); } public override Type ReturnType => _returnType; public override ParameterInfo[] GetParameters() { return _parameterTypes.Select(t => new ParameterInfo(null, t, null)).ToArray(); } }