Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8380921
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 9, 20262026-06-09T16:34:49+00:00 2026-06-09T16:34:49+00:00

I have many custom classes that I am using that I will explain and

  • 0

I have many custom classes that I am using that I will explain and post examples of. After Explaining what they all do I will try to clearly describe the conditions under which my bug is happening.

First, I am using a PropertyGrid to display the properties of several different types of objects. Because the default binding of the PropertyGrid was not what as descriptive as I wanted it to be, I created a few custom classes that I will refer to as “Display” classes. These Display classes are constructed by passing in the an object and then creating properties that return nicely formatted strings and descriptions for the public properties (and in some case methods) of the real object that was passed in.

I will demonstrate this with some abbreviated example code:

Here is an example of an object I want to Display in my PropertyGrid:

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

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

The string property “Name” displays fine in the PropertyGrid
However The CustomObject and List did not display in way that seemed very user friendly to me.

So I attempted to create a solution by writing this class:

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;}
}

As you can see in the code above, I created special DisplayClasses for both my Joint class and my CustomObject class. In my project I have many, many different kinds of objects that require the same kind of overlaping Display Class properties.

Above you can see the Lines I added above the last two properties

[TypeConverterAttribute(typeof(ExpandableObjectConverter))]

This line solves my problem of displaying the CustomObject how I want to in the propertGrid(almost… more on this later). However it does not work the same way for my Custom List property. On the Custom List it expands to show only Count and capacity(The actual properties of the List) It makes sense why this is, but it was not what I wanted. I wanted to see the actual contained object within the list.

enter image description here

So here is my complicated solution, Taken initially from this question:

I have two classes that I am using to dynamically add objects to the propertyGrid bound list in the form of properties. The first(CustomClass) can be downloaded here. It is used to Dynamically create properties. The second class(DisplayIEnumerable) I am using is derived from the first and can be found here.

The DisplayIEnumerable class loops through the list objects and adds a property to itself with the information contained within the each object. A DisplayClass is passed in to define exactly how those objects properties should be represented within the Grid.

Up to this Point everything works great! as evidenced by this picture(picture was not created using the classes provided, Strings are formatted differently in the classes I am using, removed formatting code to help you focus on the relevant code:

enter image description here

Now after that long intro, the real question. Using the techniques above I would like to write a class that can dynamically handle CustomObjects that I have not written unique display classes for. I am intending to leave this code for those using the application for testing so that they can more effectively test without having to have a complete Display Class for every one of my company’s CustomObjects. (there are hundreds) Instead, By binding the propertyGrid with the class below, I hope to have all the properties that are lists and CustomObjects that do have corresponding DisplayClasses to be bound in their place.

Here is the class that I have already tried and have a bug with. I have not yet tried implementing the replacement of Lists with my DisplayIEnumerable class yet, I wanted to get the basic functionality working first:

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
   }

When run, The PropertyGrid appears as it should:
Before

However, once you click on the Expand arrow, nothing happens, and the arrow disappears:
After

What is wrong with the class above that is not wrong with my DisplayIEnumerable class, that causes this variance in behaviour?

I am using the DisplayObject class like this(inside a DisplayClass):

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

Thanks in advance! I will be very impressed if anyone makes it through this question.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-09T16:34:51+00:00Added an answer on June 9, 2026 at 4:34 pm

    You don’t have to create special classes to use the property grid. Just decorate the properties with the proper attributes. Here is an example:

    Two custom classes:

    public class MyObjType1
    {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public override string ToString()
        {
            return Name;
        }
    }
    
    public class MyObjType2
    {
        public string Reference { get; set; }
    
        public override string ToString()
        {
            return Reference;
        }
    }
    

    Note the ToString is overriden, that’s what the property grid uses by default if no TypeConverter is defined for a given type.

    One “holder” class that has a collection of custom objects:

    public class MyHolder
    {
        public MyHolder()
        {
            Objects = new List<object>();
        }
    
        public string Name { get; set; }
    
        [TypeConverter(typeof(MyCollectionConverter))]
        public List<object> Objects { get; private set; }
    }
    

    Note the custom TypeConverter applied directly to the Objects property. Here is the source:

    public class MyCollectionConverter : ExpandableObjectConverter
    {
        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
        {
            IEnumerable enumerable = value as IEnumerable;
            if (enumerable == null)
                return base.GetProperties(context, value, attributes);
    
            int i = 0;
            List<PropertyDescriptor> list = new List<PropertyDescriptor>();
            foreach (object obj in enumerable)
            {
                MyItemPropertyDescriptor index = new MyItemPropertyDescriptor(i.ToString(), obj);
                list.Add(index);
                i++;
            }
            return new PropertyDescriptorCollection(list.ToArray());
        }
    
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType != typeof(string))
                return base.ConvertTo(context, culture, value, destinationType);
    
            IEnumerable enumerable = value as IEnumerable;
            if (enumerable == null)
                return base.ConvertTo(context, culture, value, destinationType);
    
            StringBuilder sb = new StringBuilder();
            foreach (object obj in enumerable)
            {
                if (sb.Length > 0)
                {
                    sb.Append(',');
                }
                sb.AppendFormat("{0}", obj);
            }
            return sb.ToString();
        }
    }
    

    Note we override ConvertTo and give it a special string that displays a comma-separated list of objects in the list. The GetProperties is also overriden and uses a special PropertyDescriptor; It adds an ExpandableObjectConverter attribute to sub objects so they can be expanded too:

    public class MyItemPropertyDescriptor : PropertyDescriptor
    {
        private object _value;
    
        public MyItemPropertyDescriptor(string name, object value)
            : base(name, new[] { new TypeConverterAttribute(typeof(ExpandableObjectConverter)) })
        {
            _value = value;
        }
    
        public override bool IsReadOnly
        {
            get { return false; }
        }
    
        public override object GetValue(object component)
        {
            return _value;
        }
    
        public override Type PropertyType
        {
            get { return _value == null ? typeof(object) : _value.GetType(); }
        }
    
        public override bool ShouldSerializeValue(object component)
        {
            return false;
        }
    
        public override Type ComponentType
        {
            get { return typeof(object); }
        }
    
        public override bool CanResetValue(object component)
        {
            return false;
        }
    
        public override void ResetValue(object component)
        {
        }
    
        public override void SetValue(object component, object value)
        {
        }
    }
    

    Now, here is some sample code:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
    
            MyHolder holder = new MyHolder();
            for (int i = 0; i < 3; i++)
            {
                holder.Objects.Add(new MyObjType1 { Id = i, Name = i + "Name" });
            }
            for (int i = 0; i < 3; i++)
            {
                holder.Objects.Add(new MyObjType2 { Reference = "Ref" + i });
            }
            propertyGrid1.SelectedObject = holder;
        }
    }
    

    And the result:

    enter image description here

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have this custom JSlider, which will be used in many other forms/windows. But
Projects have many tasks and a task has a custom RESTful action called 'approve'.
I have a ListView with custom Adapter . To be honest, I have many
Many applications have dialogs which have totally custom-looking dialogs, big fat tool-bars and non-rectangular
I have various custom binary files stored in perforce and for many of the
In many of our projects I have seen a few custom collection / or
I have many PowerPoint presentations that I need to be able to add to
I currently have a simple iPhone app that loads a custom subclass of UIView.
I have had some difficulties in using extended classes in rails, in particular extending
i have many objects of the same custom class, and another many objects of

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.