我想知道是否可以创建一个具有功能和扩展功能的扩展方法。类似于Html.BeginForm()的行为,因为它会生成一个完整的Html标记,我可以在<% { & } %>
标记内具体说明其内容。
例如,我可以有一个类似的视图:
<% using(Html.BeginDiv("divId")) %>
<% { %>
<!-- Form content goes here -->
<% } %>
此功能在我尝试使用this question
中的示例生成的功能的上下文中非常有用这将使我能够为我将
的类型创建容器<% var myType = new MyType(123, 234); %>
<% var tag = new TagBuilder("div"); %>
<% using(Html.BeginDiv<MyType>(myType, tag) %>
<% { %>
<!-- controls used for the configuration of MyType -->
<!-- represented in the context of a HTML element, e.g.: -->
<div class="MyType" prop1="123" prop2="234">
<!-- add a select here -->
<!-- add a radio control here -->
<!-- whatever, it represents elements in the context of their type -->
</div>
<% } %>
我意识到这会产生无效的XHTML,但我认为可能有其他好处超过这个,特别是因为这个项目不需要XHTML验证W3C标准。
由于
戴夫
答案 0 :(得分:14)
不完全确定这对于简单地定义<div>
元素有多大的价值,但不是这样的
/// <summary>
/// Represents a HTML div in an Mvc View
/// </summary>
public class MvcDiv : IDisposable
{
private bool _disposed;
private readonly ViewContext _viewContext;
private readonly TextWriter _writer;
/// <summary>
/// Initializes a new instance of the <see cref="MvcDiv"/> class.
/// </summary>
/// <param name="viewContext">The view context.</param>
public MvcDiv(ViewContext viewContext) {
if (viewContext == null) {
throw new ArgumentNullException("viewContext");
}
_viewContext = viewContext;
_writer = viewContext.Writer;
}
/// <summary>
/// Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true /* disposing */);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources
/// </summary>
/// <param name="disposing"><c>true</c> to release both
/// managed and unmanaged resources; <c>false</c>
/// to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
_disposed = true;
_writer.Write("</div>");
}
}
/// <summary>
/// Ends the div.
/// </summary>
public void EndDiv()
{
Dispose(true);
}
}
/// <summary>
/// HtmlHelper Extension methods for building a div
/// </summary>
public static class DivExtensions
{
/// <summary>
/// Begins the div.
/// </summary>
/// <param name="htmlHelper">The HTML helper.</param>
/// <returns></returns>
public static MvcDiv BeginDiv(this HtmlHelper htmlHelper)
{
// generates <div> ... </div>>
return DivHelper(htmlHelper, null);
}
/// <summary>
/// Begins the div.
/// </summary>
/// <param name="htmlHelper">The HTML helper.</param>
/// <param name="htmlAttributes">The HTML attributes.</param>
/// <returns></returns>
public static MvcDiv BeginDiv(this HtmlHelper htmlHelper, IDictionary<string, object> htmlAttributes)
{
// generates <div> ... </div>>
return DivHelper(htmlHelper, htmlAttributes);
}
/// <summary>
/// Ends the div.
/// </summary>
/// <param name="htmlHelper">The HTML helper.</param>
public static void EndDiv(this HtmlHelper htmlHelper)
{
htmlHelper.ViewContext.Writer.Write("</div>");
}
/// <summary>
/// Helps build a html div element
/// </summary>
/// <param name="htmlHelper">The HTML helper.</param>
/// <param name="htmlAttributes">The HTML attributes.</param>
/// <returns></returns>
private static MvcDiv DivHelper(this HtmlHelper htmlHelper, IDictionary<string, object> htmlAttributes)
{
TagBuilder tagBuilder = new TagBuilder("div");
tagBuilder.MergeAttributes(htmlAttributes);
htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag));
MvcDiv div = new MvcDiv(htmlHelper.ViewContext);
return div;
}
}
并使用如此
<% using (Html.BeginDiv(new Dictionary<string, object>{{"class","stripey"}}))
{ %>
<p>Content Here</p>
<% } %>
将呈现
<div class="stripey">
<p>Content Here</p>
</div>
或没有html属性
<% using (Html.BeginDiv())
{ %>
<p>Content Here</p>
<% } %>