Adding Items to ListBox, RadioList, Combobox using reflection
I'm trying to add items to a listbox,combobox, radiolist using reflection. The code I have at the moment is as follows:
public static Control ConfigureControl(Control control, ControlConfig ctrlconf)
{
if (control is TextBox)
{
// ...
}
else
{
// get the properties of the control
//
Type controlType = control.GetType();
PropertyInfo[] controlPropertiesArray = controlType.GetProperties();
foreach (PropertyInfo controlProperty in controlPropertiesArray)
{
if (controlProperty.Name == "Items" && controlProperty.PropertyType == typeof(ListItemCollection))
{
object instance = Activator.CreateInstance(controlProperty.PropertyType);
MethodInfo addMethod = controlProperty.PropertyType.GetMethod("Add", new Type[] { typeof(ListItem)} );
List<string> popValues = new List<string>(ctrlconf.PopulatedValues.Split(';'));
if (popValues.Count.Equals(0))
{
throw new ArgumentException("No values found for control");
}
else
{
foreach (string val in popValues)
{
addMethod.Invoke(instance, new object[] { new ListItem(val, val开发者_StackOverflow社区) });
}
}
}
}
}
return control;
}
The code above populates the listitemcollection which I have instantiated using Activator.CreateInstance, however I'm not sure how to add it to the ListBox.
Any help would be great.
Thanks,
Peter
You don't need or want to instantiate the collection object: that's already done by the control. Instead, you need to get the existing collection object, then add to that:
if (controlProperty.Name == "Items" && controlProperty.PropertyType == typeof(ListItemCollection))
{
object instance = controlProperty.GetValue(control, null);
// ... now go on and add to the collection ...
}
However, as others have noted, this may not be the best way to approach the problem. Instead, consider implementing adapter or strategy for the various controls you want to support e.g. RadioButtonListItemAdder, ListControlItemAdder, etc., which all conform to a common interface. Each type of XxxItemAdder can implement its own strongly-typed code, suitable for the type of control it's responsible for adding items to. This might look something like the following:
public interface IItemAdder
{
void AddItem(string value);
}
public class ListControlItemAdder : IItemAdder
{
private readonly ListControl _listControl;
public ListControlItemAdder(ListControl listControl)
{
_listControl = listControl;
}
public void AddItem(string value)
{
_listControl.Items.Add(value); // or new ListItem(value, value) per your original code
}
}
public class RadioButtonListItemAdder : IItemAdder
{
// ...
public void AddItem(string value)
{
// do whatever you have to do to add an item to a list of RadioButtons
}
}
public static IItemAdder CreateItemAdderFor(Control control)
{
if (control is ListControl)
return new ListControlItemAdder((ListControl)control);
else if (control is RadioButtonList)
return new RadioButtonListItemAdder((RadioButtonList)control);
// etc. to cover other cases
}
public static Control ConfigureControl(Control control, ...)
{
// ... omitting code that looks like your existing code ...
IItemAdder itemAdder = CreateItemAdderFor(control);
foreach (string val in popValues)
itemAdder.AddItem(val);
}
This is a really untidy implementation but hopefully gives you the idea of how you can separate out each of the individual control-specific implementations into small, nicely separated classes.
精彩评论