我目前有一个div容器,用于表单中的所有输入字段,类似于:
<div class="ux-single-field ui-widget-content ui-corner-all"> @Html.LabelFor(m => m.Name) @Html.TextBoxFor(m => m.Name) </div>
我想知道如何使用templated razor delegate(或any other trick)封装它,所以就像我们使用:
@using (Html.BeginForm()) { }
我可以简单地包装我的元素:
@using (Html.ContentField()) { @Html.LabelFor(m => m.Name) @Html.TextBoxFor(m => m.Name) }
解决方法
使用Razor View引擎,这是有效的:
namespace MyProject.Web.Helpers.Extensions { public static class LayoutExtensions { public static ContentField BeginContentField(this HtmlHelper htmlHelper) { return FormHelper(htmlHelper,new RouteValueDictionary()); } public static ContentField BeginContentField(this HtmlHelper htmlHelper,RouteValueDictionary htmlAttributes) { return FormHelper(htmlHelper,htmlAttributes); } public static void EndContentField(this HtmlHelper htmlHelper) { htmlHelper.ViewContext.Writer.Write("</div>"); } private static ContentField FormHelper(this HtmlHelper htmlHelper,IDictionary<string,object> htmlAttributes) { TagBuilder tagBuilder = new TagBuilder("div"); tagBuilder.MergeAttributes(htmlAttributes); tagBuilder.MergeAttribute("class","ux-single-field ui-widget-content ui-corner-all"); htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag)); return new ContentField(htmlHelper.ViewContext.Writer); } } public class ContentField : IDisposable { private bool _disposed; private readonly TextWriter _writer; public ContentField(TextWriter writer) { if (writer == null) throw new ArgumentNullException("writer"); _writer = writer; } [SuppressMessage("Microsoft.Security","CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")] public void Dispose() { Dispose(true /* disposing */); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!_disposed) { _disposed = true; _writer.Write("</div>"); } } public void EndForm() { Dispose(true); } } }
仅供参考:使用旧的ASPX引擎,here’s how to do it.