Question

So pretty much, what I'm trying to do is create a properties grid. It will hold things like input 0-5 or like output 1-64, which will have sub-properties like name, id, etc. Right now my code is very straight forward, and I initialize each one individually. That caused a problem when I wanted to save them to a text file and realized that doing it that way will cause walls of code. Instead of just being able to do a for loop, I would have to grab each one individually to write to the text file. I was wondering if there was a better approach to doing this with an array or list.

Here is what I have right now:

        [CategoryAttribute("Input 0"), DescriptionAttribute("Name of Input 0"), DisplayName("Input 0: Name")]
    public string IName_0
    {
        get {return _Iname[0];}
        set {_Iname[0] = value;}
    }

    [CategoryAttribute("Input 0"), DescriptionAttribute("ID of Input 0"), DisplayName("Input 0: ID")]
    public int IID_0
    {
        get { return _IID[0]; }
        set { if ((64 > value) && (value >= 0)) _IID[0] = value; }
    }
    [CategoryAttribute("Input 1"), DescriptionAttribute("Name of Input 1"), DisplayName("Input 1: Name")]
    public string IName_1
    {
        get { return _Iname[1]; }
        set { _Iname[1] = value; }
    }

    [CategoryAttribute("Input 1"), DescriptionAttribute("ID of Input 1"), DisplayName("Input 1: ID")]
    public int IID_1
    {
        get { return _IID[1]; }
        set { if ((64 > value) && (value >= 0)) _IID[1] = value; }

It goes on like that for each input. I have been looking everywhere, and I can't find a good fix.

Was it helpful?

Solution

First you have to realize that containing your properties in a collection will cause them to be grouped together under it, when displayed on your PropertyGrid.
Therefore, having a collection of strings and another of ints will break your current structure, of:

  1. Having pairs of properties (name and ID) grouped together;
  2. Having all the properties on the root level of the property grid.

Having said that, you could solve issue #1 by making #2 a bit worse.
create two classes:

  • MyClass - containing a Name and IID properties.
  • MyClassCollection - a container class (most likely using an underlying List).

To mitigate issue #2, you can add code to expand all nodes at initialization as shown here.

If you try this, you will notice that the "containers" (MyClassCollection and MyClass) will have some undesired decription text appearing next to them when displayed. This is where this article comes in handy.

Your property would then be:

[DisplayName("Some info here"),
DescriptionAttribute("Some more descriptive info here...")]
virtual public MyClassCollection MyData { get; set; }

and your class definitions would be along the lines of:

public class MyClass
{
    public string Name
    {
        get { return _name;  }
        set { _name = value; }
    }

    public int IID
    {
        get { return _iid; }
        set { if ((64 > value) && (value >= 0)) _iid = value; }
    }

    private string _name;
    private int    _iid;
}

public class MyClassCollection : CollectionBase
{
    // See the article for code for the overrides (for CollectionBase) and implementation (for ICustomTypeDescriptor)
}

If you look at the article mentioned above, regarding the tweaking of the display text of the container classes, you'll have to make some adjustments to the classes above.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top