Специальное, сложное решение для динамического отражения -C#

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

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

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

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

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

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

Строковое свойство «Имя» отлично отображается в 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 CustomList { get; set;}
}

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

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

[TypeConverterAttribute(typeof(ExpandableObjectConverter))]

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

enter image description here

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

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

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

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

enter image description here

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

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

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

   internal class DisplayObject : CustomClass
   {
      #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; } }

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

9
задан Community 23 May 2017 в 12:06
поделиться