Reputation: 1637
I want to show a drop-down of strings in a propertygrid for a selected value. In my current case, I have to bind a dictionary object to a property grid.
If I am binding a class it is easy to do as below using a TypeConverter.
public class Employee
{
public string Name { get; set; }
[TypeConverter(typeof(JobCategoryConverter))]
public int? Category { get; set; }
}
private void Form1_Load(object sender, EventArgs e)
{
Employee emp = new Employee() {Name = "Ray" ,Category = 1 };
propertyGrid1.SelectedObject = emp;
}
result look like this.
Any suggestion how I can show this dropdown if I bind to a dictionary? I used this code to bind dictionary to propertygrid.
So the code looks like,
private void Form1_Load(object sender, EventArgs e)
{
IDictionary dict = new Hashtable();
dict["Name"] = "Ray";
dict["Category"] = 1;
DictionaryPropertyGridAdapter dpg = new DictionaryPropertyGridAdapter(dict);
propertyGrid1.SelectedObject = dpg;
}
Upvotes: 2
Views: 3095
Reputation: 205759
This is relatively easy.
The idea is to allow specifying attributes for the custom DictionaryPropertyDescriptor
.
First, change the DictionaryPropertyDescriptor
class constructor to:
internal DictionaryPropertyDescriptor(IDictionary d, object key, Attribute[] attributes)
: base(key.ToString(), attributes)
{
_dictionary = d;
_key = key;
}
Then add the following to the DictionaryPropertyGridAdapter
class:
public Dictionary<string, Attribute[]> PropertyAttributes;
and change the GetProperties
method to:
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
ArrayList properties = new ArrayList();
foreach (DictionaryEntry e in _dictionary)
{
Attribute[] attrs;
if (PropertyAttributes == null || !PropertyAttributes.TryGetValue(e.Key.ToString(), out attrs))
attrs = null;
properties.Add(new DictionaryPropertyDescriptor(_dictionary, e.Key, attrs));
}
PropertyDescriptor[] props =
(PropertyDescriptor[])properties.ToArray(typeof(PropertyDescriptor));
return new PropertyDescriptorCollection(props);
}
and you are done with the required changes.
Now you can associate TypeConverter
with your "property" similar to what you do with a class like this:
enum JobCategory { Accountant = 1, Engineer, Manager }
class JobCategoryConverter : EnumConverter
{
public JobCategoryConverter() : base(typeof(JobCategory)) { }
}
private void Form1_Load(object sender, EventArgs e)
{
IDictionary dict = new Hashtable();
dict["Name"] = "Ray";
dict["Category"] = 1;
DictionaryPropertyGridAdapter dpg = new DictionaryPropertyGridAdapter(dict);
dpg.PropertyAttributes = new Dictionary<string, Attribute[]>
{
{ "Category", new Attribute[] { new TypeConverterAttribute(typeof(JobCategoryConverter)) } }
};
propertyGrid1.SelectedObject = dpg;
}
and the result will be:
You can also associate other attributes like DisplayName
, Category
etc.
Upvotes: 2