Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Dynamically add and update a combo-box's items inside a PropertyGrid control

2.57/5 (10 votes)
26 May 2007CPOL4 min read 1   1.2K  
It is not easy to dynamically control a combo-box's items inside a PropertyGrid control. This article will explain how to do that.

Sample Image - PropertyComboBox.jpg

Important: This article uses the clsPropertyComboBox class developed by the author. To demonstrate how to use the class, I used the PropertyBag class and demo made by Tony Allowatt. You should read his great article here: http://www.codeproject.com/KB/miscctrl/bending_property.aspx.

Introduction

The are so many articles and questions around the web about how to dynamically update a combo-box's items inside a PropertyGrid control. It happens when we want to use the PropertyGrid but don't want to use a hard-coded class as the list of properties. You can easily find a way to control the usual editable values by Googling the web, or even from this website.

In this article, we will discuss how to dynamically control the combo-boxes inside a PropertyGrid control. This article is for those who know what PropertyGrid is and how to use it. As a platform, I used C# with Framework 2.0 under Microsoft's Visual Studio 2005, and haven't tested in on other platforms.

Improving the class attached to this article is welcome. I'm really sure that there are so many different and better ways to do what I did, but I had only a few hours to solve it, so.. ;)

The attached demo is also based on Tony's demo app. Thanks Tony..

Background

To control the combo-boxes inside a PropertyGrid control, we need to define a class derived from UITypeEditor that returns a combo list with different items depending on the PropertyGrid control we use and the property we need to edit. Notice that the class clsPropertyComboBox will never be assigned; it uses static members to control the content (I know, I know..). Here's what I did, step by step:

First step

I created a class derived from UITypeEditor, so the PropertyGrid will be able to use its type. This class (UITypeComboBox) overrides the GetValue method to display a list with values entered dynamically (shown as a combo-box at the end of the job).

Second step

I wrote a class to wrap the UITypeComboBox class and to enable controlling each of the combo-box values. This class is called clsPropertyComboBox. I added the class methods addComboBox, addValue, Reset, etc. These methods control the values inside each combobox, in each PropertyGrid control in our application.

Third and last step

I used Tony Allowatt's PropertyBag class to see if it all works..

Using the code

Please read and download the article and files by Tony Allowatt to understand the code samples. The whole demonstration is based on it.

Don't forget to add clsPropertyComboBox to the project!

To control our comboboxes, we need to give each one of them a unique ID. The ID is given by the clsPropertyComboBox class, using the function addComboBox and three parameters:

  1. PropertyGrid.Text (you should set this property for each PropertyGrid that uses the clsPropertyComboBox class).
  2. Property's category.
  3. Property's name.

There are a few ways to use addComboBox, and you can see this in the code. (You can tell it to sort the values, or to send a null category name for the most-top category, for example).

Here is an example:

C#
...
// init the Text value og the PropertyGrid control.
propertyGrid1.Text = "props";

// get a combo unique is (string) from clsPropertyComboBox
string comboId;
comboId = PropertyBagTester.clsPropertyComboBox.addComboBox(
                            propertyGrid1.Text, "Fruit", "Misc");

Again, notice that all functions are static.

Now, after we get the combo ID, we can add or update its values, using the addValue and updateValue methods:

C#
AddValue(string categoryPath, object key, object value);
  • categoryPath = the combo ID (sorry, I know it should be called "comboId")
  • key = a combo item's key
  • value = a combo item's value (this value is what the user sees)

Example:

C#
...
PropertyBagTester.clsPropertyComboBox.addValue(comboId, "fruit1", "Apple");
PropertyBagTester.clsPropertyComboBox.addValue(comboId, "fruit2", "Orange");
PropertyBagTester.clsPropertyComboBox.addValue(comboId, "fruit3", "Banana");
PropertyBagTester.clsPropertyComboBox.addValue(comboId, "fruit4", "Olive");

Now we'll use the PropertyBag to explain how to use it:

C#
...
// using the PropertyBag
bag1 = new PropertyBag();
...

bag1.Properties.Add(new 
PropertySpec("Fruit", typeof(PropertyBagTester.clsPropertyComboBox.UITypeComboBox), 
             null, null, "Orange", 
             typeof(PropertyBagTester.clsPropertyComboBox.UITypeComboBox), 
             typeof(PropertyBagTester.clsPropertyComboBox.UITypeComboBox)));

Now we have a combo box ready to use. While running, the clsPropertyComboBox class will do the rest - when clicking the property called "Fruit" under the category "Misc", a combo-box will appear with the values "Apple", "Orange", "Banana", and "Olive".

How can we add another? Very easy, we just have to add a new combo-box by calling addComboBox again, and use the returned combo ID to init the new combo-box's values. See this:

C#
...
comboId = PropertyBagTester.clsPropertyComboBox.addComboBox(propertyGrid1.Text, 
          "test", "cat1");
PropertyBagTester.clsPropertyComboBox.addValue(comboId, "c1", "_c1");
PropertyBagTester.clsPropertyComboBox.addValue(comboId, "c2", "_c2");
...
// etc..

If you'll do that, you'll see it works. Now we might want to read the selected value from the list (although it updates itself). Remember that the selected value or key will be null if the user didn't use the combo-box.

Use the function getSelectedKey(comboId);. See how we do this:

C#
// show the selected key
private void button1_Click(object sender, EventArgs e)
{
    string comboId = 
      PropertyBagTester.clsPropertyComboBox.getComboBoxID("props", "Misc", "Fruit");
    string value = (string) 
    PropertyBagTester.clsPropertyComboBox.getSelectedKey(comboId);

    if (value != null) MessageBox.Show((string)value);
    else MessageBox.Show("user didn't select from list yet");
}

// show the selected value
private void button2_Click(object sender, EventArgs e)
{
    string comboId = 
      PropertyBagTester.clsPropertyComboBox.getComboBoxID("props", "Misc", "Fruit");
    string value = 
      (string)PropertyBagTester.clsPropertyComboBox.getSelectedValue(comboId);

    if (value != null) MessageBox.Show((string)value);
    else MessageBox.Show("user didn't select from list yet");
}

Again, thanks to Tony for the nice-to-use demo; here's the link to his article again: http://www.codeproject.com/KB/miscctrl/bending_property.aspx.

If you want to understand how I created the combo-box control, see how I implemented the GetValue method in the UITypeComboBox class. It's very easy to understand.

Hope I helped!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)