我想创建一个帮助器,我可以像Helper.BeginForm()那样在括号之间添加内容。我不介意为我的助手创建一个Begin,End,但这样做非常简单易行。
基本上我要做的是在这些标签之间包装内容,以便它们呈现为已格式化
类似
@using Html.Section("full", "The Title")
{
This is the content for this section
<p>More content</p>
@Html.TextFor("text","label")
etc etc etc
}
参数“full”是该div的css id,“title”是该部分的标题。
除了做我想做的事情之外,还有更好的方法来实现这个目标吗?
提前感谢您的帮助。
答案 0 :(得分:36)
这完全有可能。在MVC中使用Helper.BeginForm
之类的方式完成此操作的方法是函数必须返回一个实现IDisposable
的对象。
IDisposable
interface定义了一个名为Dispose
的方法,该方法在对象被垃圾收集之前调用。
在C#中,using
关键字有助于限制对象的范围,并在它离开范围时立即对其进行垃圾收集。因此,将其与IDisposable
一起使用是很自然的。
您需要实现一个实现Section
的{{1}}类。它必须在构造时为部分渲染开放标记,并在处理时渲染关闭标记。例如:
IDisposable
现在该类型可用,您可以扩展HtmlHelper。
public class MySection : IDisposable {
protected HtmlHelper _helper;
public MySection(HtmlHelper helper, string className, string title) {
_helper = helper;
_helper.ViewContext.Writer.Write(
"<div class=\"" + className + "\" title=\"" + title + "\">"
);
}
public void Dispose() {
_helper.ViewContext.Writer.Write("</div>");
}
}
答案 1 :(得分:4)
这是我写的一个小工具来做这件事。它更通用,因此您可以将它用于任何标记和任何属性。它被设置为HtmlHelper的扩展方法,因此您可以在Razor内部以及在代码内使用它。
public static class WrapUtil
{
public static IDisposable BeginWrap(this HtmlHelper helper, string tag, object htmlAttributes)
{
var builder = new TagBuilder(tag);
var attrs = GetAttributes(htmlAttributes);
if (attrs != null)
{
builder.MergeAttributes<string, object>(attrs);
}
helper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
return new WrapSection(helper, builder);
}
private static IDictionary<string, object> GetAttributes(object htmlAttributes)
{
if (htmlAttributes == null)
{
return null;
}
var dict = htmlAttributes as IDictionary<string, object>;
if (dict != null)
{
return dict;
}
return HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
}
private class WrapSection : IDisposable
{
private readonly HtmlHelper _Helper;
private readonly TagBuilder _Tag;
public WrapSection(HtmlHelper helper, TagBuilder tag)
{
_Helper = helper;
_Tag = tag;
}
public void Dispose()
{
_Helper.ViewContext.Writer.Write(_Tag.ToString(TagRenderMode.EndTag));
}
}
}