2009-11-07 54 views
0

我试图将项目添加到使用反射的列表框,组合框,radiolist。我此刻的代码如下:使用反射将项目添加到ListBox,RadioList,Combobox

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,但我不知道如何将它添加到列表框。

任何帮助将是伟大的。

感谢,

彼得

+0

为什么不把控件投到ListBox?另外,为什么你要返回Control - 它是一个引用类型,所以不需要这样做。 – 2009-11-07 22:09:06

+0

无法真正投入列表框,因为我想要使用radiolist,dropdown等方法,并且必须使用几个case语句 - 因此思考反射会更好。 – Peter 2009-11-07 22:12:45

回答

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

这是一个非常不整洁的实现,但希望给你的,你怎么能每个单独控制特定的实现分离成小,很好地分离类的想法。

+0

谢谢itowlson - 代码片段做到了!我不认为你会提供一些简单的代码来说明适配器/策略模式。再次非常感谢修复。 – Peter 2009-11-07 22:45:00

+0

Peter:更新了包含*基本*示例代码的答案,用于将控件特定的添加逻辑分解为适配器/策略。 – itowlson 2009-11-07 22:57:49

+0

谢谢itowlson - 非常感谢。 – Peter 2009-11-07 23:07:35