使用反射将项添加到ListBox,RadioList,Combobox

时间:2009-11-07 22:00:18

标签: c# reflection listbox

我正在尝试使用反射将项目添加到列表框,组合框,放射学家。我目前的代码如下:

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

                    }

                }
            }
        }

        return control;

    }

上面的代码填充了我使用Activator.CreateInstance实例化的listitemcollection,但是我不知道如何将它添加到ListBox。

任何帮助都会很棒。

谢谢,

彼得

1 个答案:

答案 0 :(得分:0)

您不需要或不想实例化集合对象:控件已经完成了该操作。相反,您需要获取现有的集合对象,然后添加到:

if (controlProperty.Name == "Items" && controlProperty.PropertyType == typeof(ListItemCollection))
{
  object instance = controlProperty.GetValue(control, null);
  // ... now go on and add to the collection ...
}

然而,正如其他人所说,这可能不是解决问题的最佳方法。相反,请考虑为您要支持的各种控件实施适配器或策略,例如RadioButtonListItemAdder,ListControlItemAdder等,它们都符合通用接口。每种类型的XxxItemAdder都可以实现自己的强类型代码,适用于它负责添加项目的控件类型。这可能类似于以下内容:

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

这是一个非常不整洁的实现,但希望能让您了解如何将每个特定于控件的实现分离成小的,分离良好的类。