剃刀基础类型/模板化剃刀代表“ using”关键字

问题描述

| 我目前在表单中的所有输入字段中都有一个“ 0”容器,类似于:
<div class=\"ux-single-field ui-widget-content ui-corner-all\">
  @Html.LabelFor(m => m.Name)
  @Html.TextBoxFor(m => m.Name)
</div>
我想知道如何使用模板化的剃刀委托(或任何其他技巧)来封装它,就像我们使用的那样:
@using (Html.BeginForm()) {
}
我可以像这样简单地包装我的元素:
@using (Html.ContentField()) {
  @Html.LabelFor(m => m.Name)
  @Html.TextBoxFor(m => m.Name)
}
    

解决方法

使用Razor View Engine,可以使用以下方法:
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引擎,这里是操作方法。     ,接受的答案非常有帮助。我为我的项目做了一些更改和更新,我觉得对于只想参与进来并完成工作的人来说,此版本会更清晰一些。 更改包括: 升级为使用匿名类型而不是IDictionary,因为现在这已成为标准。 删除了Begin / End ...语法,因为我将只将它与using()语法一起使用,因此我觉得这更加清楚。 为清楚起见,对命名进行了调整。 添加了headerText参数,我的面板用来创建单独的div标头。如果您不需要/不需要,可以轻松删除它。 重构出几种方法。 如果您恰巧在寻找KendoUI的面板帮助程序-恰好就是这样。我有一个称为panel的类,它引用了该类,并且仅向KendoUI标签添加了边距和宽度。 使用系统; 使用System.Diagnostics.CodeAnalysis; 使用System.IO; 使用System.Web.Mvc; 命名空间MyProject.Web.HtmlHelpers.Extensions {     公共静态类LayoutExtensions     {         公共静态StyledPanel面板(此HtmlHelper htmlHelper,对象htmlAttributes = null,字符串headerText = null)         {             返回GetStyledPanel(htmlHelper,headerText,htmlAttributes);         }
    private static StyledPanel GetStyledPanel(this HtmlHelper htmlHelper,string headerText,object htmlAttributes)
    {

        if (!string.IsNullOrWhiteSpace(headerText))
            RenderHeading(htmlHelper,headerText);

        RenderDiv(htmlHelper,htmlAttributes);

        return new StyledPanel(htmlHelper.ViewContext.Writer);
    }

    private static void RenderHeading(HtmlHelper htmlHelper,string headerText)
    {
        TagBuilder tagBuilder = new TagBuilder(\"div\");
        tagBuilder.Attributes.Add(\"class\",\"panelHead\");
        tagBuilder.SetInnerText(headerText);

        htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.Normal));
    }

    private static void RenderDiv(HtmlHelper htmlHelper,object htmlAttributes) 
    {
        TagBuilder Tag = new TagBuilder(\"div\");
        Tag.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        Tag.MergeAttribute(\"class\",\"panel k-block k-shadow\");

        htmlHelper.ViewContext.Writer.Write(Tag.ToString(TagRenderMode.StartTag));        
    }

}

public class StyledPanel : IDisposable
{
    private bool m_Disposed;
    private readonly TextWriter m_Writer;

    public StyledPanel(TextWriter writer)
    {
        if (writer == null)
            throw new ArgumentNullException(\"Writer was null. This should never happen.\");

        m_Writer = writer;
    }

    [SuppressMessage(\"Microsoft.Security\",\"CA2123:OverrideLinkDemandsShouldBeIdenticalToBase\")]
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!m_Disposed)
        {
            m_Disposed = true;
            m_Writer.Write(\"</div>\");
        }
    }

    public void EndForm()
    {
        Dispose(true);
    }
}
} 用法可能是这样的:
@using (Html.Panel(headerText: \"My Header\",htmlAttributes: new { style = \"width: 800px;\" }))
{ 
    <table>
            <tr>
                <td class=\"label\">First Name:</td>
                <td class=\"content\"><input name=\"thing\" class=\"k-textbox\" /></td>

                <td class=\"label\">Last Name:</td>
                <td class=\"content\"><input name=\"thing\" class=\"k-textbox\" /></td>
            </tr>
    </table>
}
要不就:
@using (Html.Panel())
{ 
    <table>
            <tr>
                <td class=\"label\">First Name:</td>
                <td class=\"content\"><input name=\"thing\" class=\"k-textbox\" /></td>

                <td class=\"label\">Last Name:</td>
                <td class=\"content\"><input name=\"thing\" class=\"k-textbox\" /></td>
            </tr>
    </table>
}
    ,让我们看一看(或猜测)
Html.BeginForm()
的作用。从“渲染角度”来看,它通常只是将开始表单标记渲染到html输出中。它是一次性的,因为在这种情况下,它知道表单的内部html内容何时完成渲染,并且可以使用in10ѭ方法渲染end9ѭ标记。有了这些,您就可以得到-首先,呈现打开的
form
标签,然后显示您想要的自定义html内容,然后是end标签。结果-您在输出中获得完整的html表单。
<form>

...contents(Result of Html.TextBoxFor,etc. helpers)

</form>
我认为您的情况最好以表格形式解决。目前我没有太多时间来编写完整的代码,但是如果您通过查看源代码(感谢@druttka)反射器来查看old13ѭ(如果您有旧版本或购买了许可证)或http://wiki.sharpdevelop.net/ilspy.ashx和上述说明,您可以从头开始。从BeginForm方法中删除不必要的代码,创建MvcContentField:IDisposable类而不是MvcForm,将其上的ѭ10更改为呈现end div标签,您将完全得到所需的内容。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...