質問

I try to create some Html Helpers which will have an opening tag and closing tag which will include other contents like the Html.BeginForm does. For example in Razor we can use the Html.BeginForm helper which has the following syntax:

    @using (Html.BeginForm())
    {
    }

This code will include the contents of curly brackets within a and . The only way that I solved opening and closing a tag with contents is by using two html helpers. I define two html helpers:

    public static MvcHtmlString StartForm(this System.Web.Mvc.HtmlHelper helper)
    {
        return new MvcHtmlString("<form>");
    }
    public static MvcHtmlString EndForm(this System.Web.Mvc.HtmlHelper helper)
    {
        return new MvcHtmlString("</form>");
    }

Then I use the helpers using the following example:

    @Html.StartForm()
    contents
    @Html.EndForm()

But I would like to be able to make one html helper which will have the following format in the view:

    @using (Html.MyForm())
    {
            <text>contents</text>
    }

Can someone help me with this problem because I do not know even how to search it.

役に立ちましたか?

解決

You can define a class just like the way the MvcForm is implemented. The class below allows you to create a tag which contains other elements.

public class MvcTag : IDisposable
{
    private string _tag;
    private bool _disposed;
    private readonly FormContext _originalFormContext;
    private readonly ViewContext _viewContext;
    private readonly TextWriter _writer;

    public MvcTag(ViewContext viewContext, string tag)
    {
        if (viewContext == null)
        {
            throw new ArgumentNullException("viewContext");
        }

        _viewContext = viewContext;
        _writer = viewContext.Writer;
        _originalFormContext = viewContext.FormContext;
        viewContext.FormContext = new FormContext();
        _tag = tag;
        Begin(); // opening the tag
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public void Begin()
    {
        _writer.Write("<" + _tag + ">");
    }

    private void End()
    {
        _writer.Write("</" + _tag + ">");
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            _disposed = true;
            End(); // Closing the tag

            if (_viewContext != null)
            {
                _viewContext.OutputClientValidation();
                _viewContext.FormContext = _originalFormContext;
            }
        }
    }

    public void EndForm()
    {
        Dispose(true);
    }
}

To make use of this MvcTag in the way the MvcForm is used, we have to define an extension

public static class HtmlHelperExtensions
{
    public static MvcTag BeginTag(this HtmlHelper htmlHelper, string tag)
    {
        return new MvcTag(htmlHelper.ViewContext, tag);
    }
}

And that's it. Now you can use it as:

@using(Html.BeginTag("div")) @* This creates a <div>, alternatively, you can create any tag with it ("span", "p" etc.) *@
{ 
    <p>Contents</p>
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top