Generic ComboBox with auto-named properties
I am writing a wrapper for a WinForms ComboBox control that will allow me to populate a List <T> dropdown, and has a Selected property that returns an item of type T (or null if nothing is selected).
Instead of having a Selected property, I would like it to be named based on the generic type automatically. For instance:
- MyDropDownList <& by GT; will have a SelectedUser property
- MyDropDownList <department> will have a SelectedDepartment property
- MyDropDownList <State> will have a SelectedState property
With LINQ, I can create anonymous types during grouping, for example:
var usersByGender = users
.GroupBy(x => x.Gender)
.Select(group => new {Gender = group.Key, List = group.ToList()});
Which will result in a list of the generated anonymous type containing the Gender property and List <User> that IntelliSense detects. The question is, can I somehow do this with properties in a generic class?
EDIT . Now I understand that I am asking for "method_missing" in C # 3.0, which is probably not possible. However, I am open to suggestions.
a source to share
I don't think you can do this. The only approach that even has a remote chance of working is to create some sort of factory method that created the type and returned it. Basically your generic type becomes the base class, and the IL is dynamically written, creating a concrete class that inherits from the generic, but with a new addition added. Of course, the returned object will be truly anonymous, and you will only be able to access this through reflection, because you will not have a type to overlay:
public static class CrazyFactory
{
public static object CreateTypedComboList<T>()
{
//magic happens
return object;
}
}
Using this would require
object userCombo = CrazyFactory.CreateTypedComboList<User>();
PropertyInfo selectedUserProperty = userCombo.GetType().GetProperty("SelectedUser");
selectedUserProperty.SetValue(userCombo, user);
This is unlikely to be a step up from the simple T SelectedItem property.
From a quick overview, we can see that this type of thing will be easier when C # 4.0 brings us dynamic types. By implementing the IDynamicObject interface, it will be possible to catch all undefined property calls and handle them so that you can use the logic like this:
public override MetaObject GetMember(GetMemberAction action, MetaObject[] args)
{
//not sure on the real property name here...
string actionName = action.Name;
if (actionName = "Selected" + typeof(T).Name)
{
return SelectedItem; //in some MetaObject wrapper
}
}
I have been following this article and haven't touched on dynamics yet, but it certainly looks like what you want. I won't do that anyway - you won't get Intellisense, and it seems like a fragile and complex method of defining functionality.
a source to share