Есть ли способ отображения статических свойств в PropertyGrid? - PullRequest
0 голосов
/ 30 мая 2019

У меня есть PropertyGrid, который отображает все свойства экземпляра для объекта.Есть ли способ также отобразить статические свойства класса, к которому принадлежит объект, в том же или отдельном PropertyGrid?Кроме того, есть ли другой элемент управления Forms, который позволил бы мне сделать это?

1 Ответ

0 голосов
/ 30 мая 2019

Дескрипторы типов отвечают за предоставление списка свойств для PropertyGrid.Чтобы настроить список свойств, вам нужно предоставить описание пользовательского типа для вашего класса / объекта.Для этого вы можете использовать любую из следующих опций:

  • Ваш класс может реализовать ICustomTypeDescriptor
  • Ваш класс может быть производным от CustomTypeDescriptor
  • Youможет создать новый TypeDescriptor и зарегистрировать его для вашего класса или экземпляра объекта

Пример

Допустим, у вас есть такой класс:

public class MyClass
{
    public string InstanceProperty { get; set; }
    public static string StaticProperty { get; set; } = "Test";
}

И вы хотите показать его свойства в PropertyGrid.

Тогда обычно первое, что вам нужно, это новый дескриптор свойства:

using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
public class StaticPropertyDescriptor : PropertyDescriptor
{
    PropertyInfo p;
    Type owenrType;
    public StaticPropertyDescriptor(PropertyInfo pi, Type owenrType)
        : base(pi.Name,
              pi.GetCustomAttributes().Cast<Attribute>().ToArray())
    {
        p = pi;
        this.owenrType = owenrType;
    }
    public override bool CanResetValue(object c) => false;
    public override object GetValue(object c) => p.GetValue(null);
    public override void ResetValue(object c) { }
    public override void SetValue(object c, object v) => p.SetValue(null, v);
    public override bool ShouldSerializeValue(object c) => false;
    public override Type ComponentType { get { return owenrType; } }
    public override bool IsReadOnly { get { return !p.CanWrite; } }
    public override Type PropertyType { get { return p.PropertyType; } }
}

Затем выМожно использовать любой из вариантов, которые я упоминал выше.Например, здесь я создал дескриптор типа оболочки, чтобы он не касался исходного класса:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
public class CustomObjectWrapper : CustomTypeDescriptor
{
    public object WrappedObject { get; private set; }
    private IEnumerable<PropertyDescriptor> staticProperties;
    public CustomObjectWrapper(object o)
        : base(TypeDescriptor.GetProvider(o).GetTypeDescriptor(o))
    {
        WrappedObject = o;
    }
    public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        var instanceProperties = base.GetProperties(attributes)
            .Cast<PropertyDescriptor>();
        staticProperties = WrappedObject.GetType()
            .GetProperties(BindingFlags.Static | BindingFlags.Public)
            .Select(p => new StaticPropertyDescriptor(p, WrappedObject.GetType()));
        return new PropertyDescriptorCollection(
            instanceProperties.Union(staticProperties).ToArray());
    }
}

И использование довольно простое:

var myClass = new MyClass();
propertyGrid1.SelectedObject = new CustomObjectWrapper (myClass);

enter image description here

...