在您的 Views/Shared/EditorTemplates 文件夹中创建一个名为 DateTime.ascx 的局部视图。
此 EditorTemplate 的代码应该类似于
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DateTime?>" %>
<%
string controlId = ViewData.TemplateInfo.HtmlFieldPrefix.Replace('.', '_');
%>
<script type="text/javascript">
$(function () {
$('#<%: controlId %>_Day, #<%: controlId %>_Month, #<%: controlId %>_Year').live('change', function () { updateHiddenDate('<%: controlId %>'); });
$('#<%: controlId %>_Day').val('<%: Model.HasValue ? Model.Value.Day.ToString() : "" %>');
$('#<%: controlId %>_Month').val('<%: Model.HasValue ? Model.Value.Month.ToString() : "" %>');
$('#<%: controlId %>_Year').val('<%: Model.HasValue ? Model.Value.Year.ToString() : "" %>');
updateHiddenDate('<%: controlId %>');
});
function updateHiddenDate(hiddenDateId) {
$('#' + hiddenDateId).val($('#' + hiddenDateId + '_Year').val() + "-" + $('#' + hiddenDateId + '_Month').val() + "-" + $('#' + hiddenDateId + '_Day').val());
}
</script>
<select id="<%: controlId %>_Day">
<% for (int dayOrdinal = 1; dayOrdinal <= 31; dayOrdinal++)
{
Response.Write(string.Format("<option value=\"{0}\">{0}</option>", dayOrdinal));
}
%>
</select>
<select id="<%: controlId %>_Month">
<% for (int monthOrdinal = 1; monthOrdinal <= 12; monthOrdinal++)
{
Response.Write(string.Format("<option value=\"{0}\">{1}</option>", monthOrdinal, System.Globalization.DateTimeFormatInfo.CurrentInfo.MonthNames[monthOrdinal - 1]));
}
%>
</select>
<select id="<%: controlId %>_Year">
<% for (int yearOrdinal = DateTime.Now.Year - 5; yearOrdinal <= DateTime.Now.Year + 5; yearOrdinal++)
{
Response.Write(string.Format("<option value=\"{0}\">{0}</option>", yearOrdinal));
}
%>
</select>
<%: Html.Hidden("", Model.HasValue ? String.Format("{0:yyyy-MM-dd}", Model) : "") %>
这将创建一个编辑器模板,其中包含一个隐藏字段,其中包含 MVC ModelBinder 可以解析的日期的 ISO 8601 表示。
每当下拉列表更改时,jQuery 都会更新隐藏字段。注意我使用ViewData.TemplateInfo.HtmlFieldPrefix 来获取隐藏字段的生成id。
请注意,此解决方案无需费心使用自定义 ModelBinders 即可轻松加入,因为我们构建了包含完整日期时间的单个表单值。但是,这确实意味着
- 您依赖启用了 javascript 的客户端,并且
- 您需要在母版页中包含对 jQuery 库的脚本引用(例如
<script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script>)
如果这不可接受,您将不得不查看 @Jon 指出的自定义 ModelBinders。