I'm creating a custom web server control (extends Panel) that contains a ListControl object. I want the ListControl type to be flexible, i.e. allow the type of the ListControl to be specified in the aspx markup. Currently I'm examining the user's choice and initialising the control using a switch statement:
public ListControl ListControl { get; private set; }
private void InitialiseListControl(string controlType) {
switch (controlType) {
case "DropDownList":
ListControl = new DropDownList();
break;
case "CheckBoxList":
ListControl = new CheckBoxList();
break;
case "RadioButtonList":
ListControl = new RadioButtonList();
break;
case "BulletedList":
ListControl = new BulletedList();
break;
case "ListBox":
ListControl = new ListBox();
break;
default:
throw new ArgumentOutOfRangeException("controlType", controlType, "Invalid ListControl type specified.");
}
}
Surely there is a more elegant way to do this... obviously I could allow the client code to create the object instead but I want to eliminate the need to use any code other than the aspx markup. Any suggestions would be appreciated. Thanks.
You could use a dictionary:
Dictionary<string, Type> types = new Dictionary<string, Type>();
types.Add("DropDownList", typeof(DropDownList));
...
private void InitialiseListControl(string controlType)
{
if (types.ContainsKey(controlType))
{
ListControl = (ListControl)Activator.CreateInstance(types[controlType]);
}
else
{
throw new ArgumentOutOfRangeException("controlType", controlType, "Invalid ListControl type specified.");
}
}
but if you want to be even more flexible, you can bypass the dictionary and use a little bit of reflection:
private void InitialiseListControl(string controlType)
{
Type t = Type.GetType(controlType, false);
if (t != null && typeof(ListControl).IsAssignableFrom(t))
{
ListControl = (ListControl)Activator.CreateInstance(t);
}
else
{
throw new ArgumentOutOfRangeException("controlType", controlType, "Invalid ListControl type specified.");
}
}
EDIT: Or if you want the consumer to only have access to the class (since the method is private) you could make the class generic
public class MyController<TList> where TList : ListControl, new()
{
public TList ListControl { get; private set; }
}
Check out http://weblogs.asp.net/leftslipper/archive/2007/12/04/how-to-allow-generic-controls-in-asp-net-pages.aspx
This sounds like you may want to use generics
private void InitialiseListControl<TList>() where TList : ListControl, new()
{
ListControl = new TList();
}
See MSDN docs for more information on generic methods: http://msdn.microsoft.com/en-us/library/twcad0zb(v=vs.80).aspx
Note, the article explains generic methods and how the where
keyword is used. But it doesn't explain how the new
keyword is used. The new
keyword specifies that the type argument you provide must have a default constructor. A comment below the article gives another example that uses the new keyword.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With