ASP.NET MVC2自定义控件

时间:2011-02-03 21:06:40

标签: asp.net asp.net-mvc asp.net-mvc-2

哪种创建自定义表单控件的MVC方式(如自定义下拉列表)? 我需要一种方法来创建这样的控件并在几页中重用它。我想使用默认绑定器 在调用action方法时绑定选定的值。 有人可以给出一个简单的例子吗?

这是我目前的解决方案,据我所知,设计得不是很好。

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) %> 
...

当我尝试将此DropDownViewModel包含到像这样的其他视图模型中时出现问题:

GeneralUserInfoViewModel.cs

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

AccountController.cs

...
public ActionResult EditGeneralUserInfo(GeneralUserInfoViewModel info) { 

}
...

这要正常工作BindName应设置为“Gender.SelectedValue”。这可以通过在RegisterUserViewModel中设置BindName来解决。但是如果GeneralUserInfoViewModel是另一个视图模型的一部分会发生什么:

RegisterUserViewModel.cs

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

现在BindName应设置为“GeneralInfo.Gender.SelectedValue”,以便使用默认绑定器正常工作:

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

等 如何处理这种分层?如何在DropDownVoewModel中确定应该为BindName attr设置什么?或者还有另一种更好的方法来实现它吗?

1 个答案:

答案 0 :(得分:3)

最常见的方式是:

  • 创建一个htmlhelper,您可以调用它来呈现您的控件。这是最强大,最干净的方法,但由于你需要在c#中组装html标记,所以也相当繁琐。

  • 将您的控件放在部分页面中,并调用Html.RenderPartial或Html.Partial进行渲染。这样做的好处是你可以编写html标记。它比c#html助手更容易,更易读。

您也可以使用两者的混合物。或者使用基于强视角模型的第二种方法,让viewmodel进行初始化,同时为这些方法提供一种混合。

ASP.NET MVC 3还引入了一种新的html帮助程序,它更适合构建可重用的控件库。好处是你可以在Razor视图引擎标记中编写你的html助手。有关详细信息,请参阅this blog article

编辑:我实现通用ajaxed下拉列表的方式实际上与我上面提到的两个不同。它的工作原理如下:

  1. 为下拉列表创建编辑器模板
  2. 使用Html.EditorFor()呈现编辑器模板
  3. 我的模型每个下拉列表有两个属性:值和选项。该值使用DisplayHint属性进行修饰,以便始终使用下拉列表编辑器模板
  4. 进行渲染

    ASP.NET MVC自动处理任何模型上下文前缀。如果你不熟悉编辑器模板:Brad Wilson写了一篇关于此的非常好的blog article series