Пользовательское, сложное, динамическое решение для отражения - C #

У меня есть много пользовательских классов, которые я использую, которые я объясню и опубликую примеры. После объяснения того, что они все делают, я попытаюсь четко описать условия, при которых происходит моя ошибка.

Во-первых, я использую PropertyGrid для отображения свойств нескольких различных типов объектов. Поскольку привязка по умолчанию для PropertyGrid была не такой описательной, как мне хотелось бы, я создал несколько пользовательских классов, которые я буду называть & quot; Показать & quot; классы. Эти классы Display создаются путем передачи объекта a, а затем создания свойств, которые возвращают красиво отформатированные строки и описания открытых свойств (и в некоторых случаях методов) реального объекта, который был передан.

Я продемонстрирую это с помощью некоторого сокращенного примера кода:

Вот пример объекта, который я хочу отобразить в моей PropertyGrid:

public class Joint
{
   public Joint(...)
   {...}

   //properties
   public string Name { get; set;}
   public CustomObject CC { get; set;}
   public List<CustomObject> Custom List { get; set;}
}

Строковое свойство & quot; Имя & quot; хорошо отображается в PropertyGrid Однако CustomObject и List не отображались так, как мне показалось, очень удобным для пользователя.

Поэтому я попытался создать решение, написав этот класс:

public class DisplayJoint
{       

   private Joint _jnt;

   public DisplayJoint(Joint jnt)
   {
      _jnt = jnt;
   }

   //properties
   public string Name {  get { return _jnt.Name; } }

   [TypeConverterAttribute(typeof(ExpandableObjectConverter))]
   public DisplayCustomObject CC {  get { return new DisplayCustomObject(_jnt.CC); } }

   [TypeConverterAttribute(typeof(ExpandableObjectConverter))]
   public List<CustomObject> CustomList { get; set;}
}

Как вы можете видеть из приведенного выше кода, я создал специальные DisplayClasses как для своего класса Joint, так и для своего класса CustomObject. В моем проекте у меня много, много разных типов объектов, которые требуют одного и того же вида перекрывающихся свойств класса отображения.

Выше вы можете увидеть Линии, которые я добавил выше двух последних свойств

[TypeConverterAttribute(typeof(ExpandableObjectConverter))]

Эта строка решает мою проблему отображения CustomObject, как я хочу в ProperTGrid (почти ... подробнее об этом позже). Однако это не работает так же для моего свойства пользовательского списка. В пользовательском списке он расширяется, показывая только количество и емкость (фактические свойства списка). Имеет смысл, почему это так, но это было не то, что я хотел. Я хотел видеть фактический содержащийся объект в списке.

enter image description here

Итак, вот мое сложное решение, взятое изначально изэтот вопрос:

У меня есть два класса, которые я использую для динамического добавления объектов в связанный список propertyGrid в форме свойств. Первый (CustomClass) может бытьскачать здесь, Он используется для динамического создания свойств. Второй класс (DisplayIEnumerable), который я использую, является производным от первого и может быть найденВот.

Класс DisplayIEnumerable просматривает объекты списка и добавляет к нему свойство с информацией, содержащейся в каждом объекте. Передается DisplayClass, чтобы точно определить, как свойства этих объектов должны быть представлены в Grid.

До этого момента все прекрасно работает! как видно из этого рисунка (рисунок не был создан с использованием предоставленных классов, строки в разных классах форматируются по-разному, удален код форматирования, чтобы помочь вам сосредоточиться на соответствующем коде:

enter image description here

Теперь после этого длинного вступления, реальный вопрос. Используя вышеописанные методы, я хотел бы написать класс, который может динамически обрабатывать объекты CustomObject, для которых я не написал уникальные классы отображения. Я намерен оставить этот код для тех, кто использует приложение для тестирования, чтобы они могли более эффективно тестировать, не имея полного класса отображения для каждого из пользовательских объектов моей компании. (есть сотни) Вместо этого, связывая propertyGrid с классом ниже, я надеюсь получить все свойства, которые являются списками и CustomObjects, у которых есть соответствующие DisplayClasses, которые будут связаны на своем месте.

Вот класс, который я уже пробовал и с ошибкой. Я еще не пытался реализовать замену списков моим классом DisplayIEnumerable, я хотел, чтобы сначала работали основные функции:

using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Reflection;
using System.Collections;
using System.Windows.Forms;

   internal class DisplayObject : CustomClass<T>
   {
      #region Variables
      protected T _obj;
      #endregion

      #region Constructor
      public DisplayObject(T obj)
      {
         if (obj != null)
         {
            try
            {
               Type currentType = typeof(T);
               foreach (PropertyInfo propertyInfo in currentType.GetProperties())
               {
                  Attribute[] attributes = new Attribute[1];
                  if (propertyInfo.GetType() is IEnumerable)
                     attributes[0] = new TypeConverterAttribute(typeof(ExpandableObjectConverter));
                  else
                     attributes[0] = null;
                  this.Add(new CustomProperty(propertyInfo.Name, propertyInfo, propertyInfo.GetType(), false, true, attributes));
               }
            }
            catch
            {
               MessageBox.Show("Failure!");
            }
         }
      }
      #endregion

      #region Properties
      [Browsable(false)]
      public object Item
      {
         get { return _obj; }
         set { _obj = value; }
      }
      #endregion
   }

При запуске PropertyGrid выглядит следующим образом: Before

Однако после нажатия стрелки «Развернуть» ничего не происходит, и стрелка исчезает: After

Что не так с классом выше, что не так с моим классом DisplayIEnumerable, что вызывает эту разницу в поведении?

Я использую класс DisplayObject следующим образом (внутри DisplayClass):

  [TypeConverterAttribute(typeof(ExpandableObjectConverter))]
  public DisplayObject EndJoint { get { if (_member.bcEnd != null) { return new DisplayObject(_member.EndJoint); } else return null; } }

Заранее спасибо! Я буду очень впечатлен, если кто-нибудь справится с этим вопросом.

Ответы на вопрос(2)

Ваш ответ на вопрос