Что требуется для класса, чтобы сетка свойств показывала его свойства? - PullRequest
0 голосов
/ 01 июня 2019

Язык: C # .Net Framework 4.6.1

Операционная система: Windows 7 Home 64 бит

Может кто-нибудь сказать мне, что требуется от класса для сетки свойств для отображения его свойств?

Я попытался просто унаследовать и реализовать ICustomTypeDescriptor, но ничего не отображается.

Я хотел бы, чтобы таблица свойств также пыталась проанализировать значения вместо простого принятия строки, и я бы хотелачтобы можно было указать категорию.

вот мой код ..

using System;
using System.Collections;
using System.Dynamic;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Collections.Specialized;
using System.ComponentModel;

namespace PureCore.Library.Data
{

    public class Property : DynamicObject, ICustomTypeDescriptor
    {
        private Dictionary<string, object> Properties = new Dictionary<string, object>();

        public override bool TryGetMember(GetMemberBinder binder, out object value)
        {
            if (Properties.ContainsKey(binder.Name))
            {
                value = Properties[binder.Name];
                return true;
            }
            return base.TryGetMember(binder, out value);
        }
        public override bool TrySetMember(SetMemberBinder binder,     object value)
        {  
            if (Properties.ContainsKey(binder.Name))
            {
                Properties[binder.Name] = value;
                return true;
            }

            Properties.Add(binder.Name, value);
            return true;
        }

        public AttributeCollection GetAttributes()
        {
            return TypeDescriptor.GetAttributes(this, true);
        }
        public string GetClassName()
        {
            return TypeDescriptor.GetClassName(this, true);
        }
        public string GetComponentName()
        {
            return TypeDescriptor.GetComponentName(this, true);
        }
        public TypeConverter GetConverter()
        {
            return TypeDescriptor.GetConverter(this, true);
        }
        public EventDescriptor GetDefaultEvent()
        {
            return TypeDescriptor.GetDefaultEvent(this, true);
        }
        public PropertyDescriptor GetDefaultProperty()
        {
            return TypeDescriptor.GetDefaultProperty(this, true);
        }
        public object GetEditor(Type editorBaseType)
        {
            return TypeDescriptor.GetEditor(this, editorBaseType, true);
        }
        public EventDescriptorCollection GetEvents()
        {
            return TypeDescriptor.GetEvents(this, true);
        }
        public EventDescriptorCollection GetEvents(Attribute[] attributes)
        {
            return TypeDescriptor.GetEvents(this, attributes, true);
        }
        public PropertyDescriptorCollection GetProperties()
        {
            return TypeDescriptor.GetProperties(this, true);
        }
        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            return TypeDescriptor.GetProperties(this, attributes, true);
        }
        public object GetPropertyOwner(PropertyDescriptor pd)
        {
            return this;
        }
    }
}
using PureCore.Library.Data;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Editor
{
    public partial class EnemyEditor : Form
    {
        dynamic property = new Property();
        public EnemyEditor()
        {
            InitializeComponent();
            property.HI = "Hello";
            propertyGrid1.SelectedObject = property;
        }

    }
}

1 Ответ

1 голос
/ 01 июня 2019

Вы должны добавить немного больше кода, в частности, вы должны явно дать сетке список свойств, происходящих из PropertyDescriptor , что-то вроде этого:

public class CustomType : DynamicObject, ICustomTypeDescriptor
{
    private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();

    public AttributeCollection GetAttributes() => new AttributeCollection();
    public string GetClassName() => null;
    public string GetComponentName() => null;
    public TypeConverter GetConverter() => null;
    public EventDescriptor GetDefaultEvent() => null;
    public PropertyDescriptor GetDefaultProperty() => null;
    public object GetEditor(Type editorBaseType) => null;
    public EventDescriptorCollection GetEvents() => GetEvents(null);
    public EventDescriptorCollection GetEvents(Attribute[] attributes) => new EventDescriptorCollection(null);
    public PropertyDescriptorCollection GetProperties() => GetProperties(null);
    public object GetPropertyOwner(PropertyDescriptor pd) => this;
    public PropertyDescriptorCollection GetProperties(Attribute[] attributes) => new PropertyDescriptorCollection(_properties.Select(p => new CustomProperty(p.Key, p.Value, "Mycats")).ToArray());

    public override bool TryGetMember(GetMemberBinder binder, out object value) => _properties.TryGetValue(binder.Name, out value);
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _properties[binder.Name] = value;
        return true;
    }
}

public class CustomProperty : PropertyDescriptor
{
    public CustomProperty(string name, object value, string category)
        : base(name, new Attribute[] { new CategoryAttribute(category) })
    {
        Value = value;
    }

    public object Value { get; set; }
    public override Type ComponentType => typeof(CustomType);
    public override bool IsReadOnly => false;
    public override Type PropertyType => Value != null ? Value.GetType() : typeof(object);
    public override bool CanResetValue(object component) => false;
    public override object GetValue(object component) => Value;
    public override void ResetValue(object component) => throw new NotSupportedException();
    public override void SetValue(object component, object value) => Value = value;
    public override bool ShouldSerializeValue(object component) => false;
}
...