Чтобы настроить список свойств для объекта, вы можете использовать собственный дескриптор типа для объекта. Для этого вы можете использовать одну из следующих опций:
- Ваш класс может реализовать
ICustomTypeDescriptor
- Ваш класс может быть производным от
CustomTypeDescriptor
- Вы можете создать новый
TypeDescriptor
и зарегистрировать его для своего класса или экземпляра объекта
Пример
Здесь, в этом примере, я создал класс с именем MyClass
, у которого есть список пользовательских свойств. Реализуя ICustomTypeDescriptor
для класса, я покажу List<CustomProperty>
как обычные свойства в сетке свойств.
При использовании этого механизма настраиваемые свойства также могут использоваться для привязки данных.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
public class MyClass : ICustomTypeDescriptor
{
public string OriginalProperty1 { get; set; }
public string OriginalProperty2 { get; set; }
public List<CustomProperty> CustomProperties { get; set; }
#region ICustomTypeDescriptor
public AttributeCollection GetAttributes() => TypeDescriptor.GetAttributes(this, true);
public string GetClassName() => TypeDescriptor.GetClassName(this, true);
public string GetComponentName() => TypeDescriptor.GetComponentName(this, true);
public TypeConverter GetConverter() => TypeDescriptor.GetConverter(this, true);
public EventDescriptor GetDefaultEvent() => TypeDescriptor.GetDefaultEvent(this, true);
public PropertyDescriptor GetDefaultProperty()
=> TypeDescriptor.GetDefaultProperty(this, true);
public object GetEditor(Type editorBaseType)
=> TypeDescriptor.GetEditor(this, editorBaseType, true);
public EventDescriptorCollection GetEvents() => TypeDescriptor.GetEvents(this, true);
public EventDescriptorCollection GetEvents(Attribute[] attributes)
=> TypeDescriptor.GetEvents(this, attributes, true);
public PropertyDescriptorCollection GetProperties() => GetProperties(new Attribute[] { });
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
var properties = TypeDescriptor.GetProperties(this, attributes, true)
.Cast<PropertyDescriptor>()
.Where(p => p.Name != nameof(this.CustomProperties))
.Select(p => TypeDescriptor.CreateProperty(this.GetType(), p,
p.Attributes.Cast<Attribute>().ToArray())).ToList();
properties.AddRange(CustomProperties.Select(x => new CustomPropertyDescriptor(this, x)));
return new PropertyDescriptorCollection(properties.ToArray());
}
public object GetPropertyOwner(PropertyDescriptor pd) => this;
#endregion
}
CustomProperty
Этот класс имитирует пользовательское свойство:
public class CustomProperty
{
public string Name { get; set; }
public object Value { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public string Category { get; set; } = "Custom Properties";
}
CustomPropertyDescriptor
Этот класс является дескриптором пользовательского свойства, который описывает CustomProperty
:
public class CustomPropertyDescriptor : PropertyDescriptor
{
object o;
CustomProperty p;
internal CustomPropertyDescriptor(object owner, CustomProperty property)
: base(property.Name, null) { o = owner; p = property; }
public override Type PropertyType => p.Value?.GetType() ?? typeof(object);
public override void SetValue(object c, object v) => p.Value = v;
public override object GetValue(object c) => p.Value;
public override bool IsReadOnly => false;
public override Type ComponentType => o.GetType();
public override bool CanResetValue(object c) => false;
public override void ResetValue(object c) { }
public override bool ShouldSerializeValue(object c) => false;
public override string DisplayName => p.DisplayName ?? base.DisplayName;
public override string Description => p.Description ?? base.Description;
public override string Category => p.Category ?? base.Category;
}
Использование
private void Form1_Load(object sender, EventArgs e)
{
var o = new MyClass();
o.CustomProperties = new List<CustomProperty>()
{
new CustomProperty
{
Name ="Property1",
DisplayName ="First Property",
Value ="Something",
Description = "A custom description.",
},
new CustomProperty{ Name="Property2", Value= 100},
new CustomProperty{ Name="Property3", Value= Color.Red},
};
propertyGrid1.SelectedObject = o;
}
![enter image description here](https://i.stack.imgur.com/4udO9.png)