Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusable editor template with DropDownList for business objects

I'm using MVC3 with Razor views and would like to build reusable DropDownLists for several of my classes, but after much searching I have not found an example that performs exactly how I need it...

For this example I have two classes like this:-

public class Person
{
  public int ID { get; set; }
  public string Name { get; set; }
  public Group Group { get; set; }
}

public class Group
{
  public int ID { get; set; }
  public string Name { get; set; }
}

I have a working Controller/View for Person. The view has a DropDownListFor control:

@model Person

...

@Html.DropDownListFor(o => o.Group.ID, (ViewData["groups"] as SelectList))

The view uses the Person class directly, not an intermediary model, as I haven't found a compelling reason to abstract one from the other at this stage.

The above works fine... in the controller I grab the value from Group.ID in the Person returned from the view, look it up, and set Person.Group to the result. Works, but not ideal.

I've found a binder here: MVC DropDownList values posted to model aren't bound that will work this out for me, but I haven't got that working yet... as it only really seems useful if I can reuse.

What I'd like to do is have something like this in a template:-

@model Group

@Html.DropDownListFor(o => o.Group.ID, (ViewData["groups"] as SelectList))

And use it in a view like this:-

@Html.EditorFor(o => o.Group)

However the above doesn't seem to work... the above EditorFor line inserts editors for the whole class (e.g. a textbox for Group.Description as well)... instead of inserting a DropDownList with my groups listed

I have the above template in a file called Group.cshtml under Views/Shared/EditorTemplates

If this worked, then whenever a class has a property of type Group, this DropDownList editor would be used by default (or at least if specified by some attribute)

Thanks in advance for any advice provided...

like image 705
Aleks Avatar asked Jul 19 '11 08:07

Aleks


1 Answers

You can create a drop down list user control to handle this. Under your Shared folder create a folder called EditorTemplates and place your user control there. MVC, by convention, looks in the Shared/EditorTemplates for any editor templates. You can override where it looks for the editor templates but I won't go in to that here.

Once you have your user control created, you'll need to decorate the appropriate property with the "UIHint" attribute to tell the engine what editor it should use for that property.

Following would be a sample implementation.

In the Shared/EditorTemplates folder your user control (_GroupsDropDown.cshtml in this case) would look like:

@model Group

@Html.DropDownListFor(o => o.ID, (ViewData["groups"] as SelectList))

Modify the Group property in the Person to add the UIHint attribute as follows:

**[UIHint("_GroupsDropDown")]**
public Group Group { get; set; }

In your controller you would need

ViewData["groups"] = new SelectList(<YourGroupList>, "ID", "Name");

Once you have the above code you can use the EditorFor syntax like you desire.

Hope this helps.

like image 159
kingrazor Avatar answered Sep 23 '22 05:09

kingrazor