2009-11-07 6 views
0

리플렉션을 사용하여 목록 상자, 콤보 박스, 라디오리스트에 항목을 추가하려고합니다.리플렉션을 사용하여 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로 전송하지 않습니까? 또한 컨트롤을 반환하는 이유는 무엇입니까? 참조 형식이므로이를 수행 할 필요가 없습니다. –

+0

방사성리스트, 드롭 다운 등의 메소드를 사용하고 싶고, 몇 가지 case 문을 사용해야하므로 캔트가 실제로 목록 상자로 캐스팅됩니다. 따라서 반사가 더 좋을 것이라고 생각했습니다. – Peter

답변

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

+0

Peter : 특정 컨트롤 추가 로직을 어댑터/전략에 적용하기위한 초보자 * 예제 코드를 포함하도록 답변을 업데이트했습니다. – itowlson

+0

감사합니다. itowlson - 많이 감사합니다. – Peter