简体   繁体   中英

ASP.NET MVC2 custom control

Which is the right MVC way to create custom form control (like custom drop down)? I need a way to create such control and re-use it in few pages. I want to use default binder to bind the selected value when action method is called. Can someone give a simple example how this is done?

Here is my current solution which by my opinion is not designed very well.

DropDownViewModel.cs

class DropDownViewModel {
    ...
    public string BindName {get; set;} // the name that default binder uses to bind to action param
    public int SelectedValue {get;set;} // this value should be set when user use the drop down
    ...
}

DropDown.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DropDownViewModel>" %>
...
<%= Html.TextBox(Model.BindName) %> 
...

The problem comes when I try to include this DropDownViewModel into some other view model like this one:

GeneralUserInfoViewModel.cs

class GeneralUserInfoViewModel {
    ...
    public DropDownViewModel Gender {get;set;}
    ...
}

AccountController.cs

...
public ActionResult EditGeneralUserInfo(GeneralUserInfoViewModel info) { 

}
...

This to work properly BindName should be set to "Gender.SelectedValue". This can be resolved by setting BindName in RegisterUserViewModel. But what happen if GeneralUserInfoViewModel is part of another view model like:

RegisterUserViewModel.cs

class RegisterUserViewModel {
    ...
    public GeneralUserInfoViewModel GeneralInfo {get;set;}
    ...
}

Now the BindName should be set to "GeneralInfo.Gender.SelectedValue" in order this to work properly with default binder:

...
public ActionResult RegisterUser(RegisterUserViewModel info) { ... }
...

and etc. How this layering can be handled? How can I determine what should be set to BindName attr in DropDownVoewModel? Or is there another better way to implement it?

The most common ways would be these:

  • Create a htmlhelper that you can call to render your control. This is the most powerful and the cleanest method, but also quite tedious since you need to assemble html markup in c#.

  • Put your control in a partial page and call Html.RenderPartial or Html.Partial to render it. This has the advantage that you can write html markup. It's easier and better readable than c# html helpers.

You could also use a mixture of both. Or use the second approach with a strongly based viewmodel and let the viewmodel do the initialization, giving you a kind of mixture between these approaches as well.

ASP.NET MVC 3 also introduces a new kind of html helper, which is better suited for building a reusable library of controls. The good thing about is that you can write your html helpers in Razor view engine markup. See this blog article for more details.

Edit: The way I implemented a generic ajaxed dropdownlist is as actually different from the two I mentioned above. It works as follows:

  1. Create an editor template for dropdownlists
  2. Use Html.EditorFor() to render editor templates
  3. My Models have two properties per dropdownlist: The value and the options. The value is decorated with a DisplayHint attribute so that it is always rendered with the dropdownlist editor template

ASP.NET MVC takes care of any model context prefixes automatically. In case you are not familiar with editor templates: Brad Wilson has written a very nice blog article series about this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM