2010-03-12 10 views
9

Tôi tự hỏi liệu có thể tạo phương thức mở rộng có chức năng & hành vi tương tự như Html.BeginForm(), trong đó nó sẽ tạo thẻ Html hoàn chỉnh và tôi có thể xác định nội dung của nó bên trong các thẻ <% { & } %>.Tạo Phương thức Mở rộng để Tạo Thẻ Mở & Đóng như Html.BeginForm()

Ví dụ, tôi có thể có một cái nhìn như:

<% using(Html.BeginDiv("divId")) %> 
<% { %> 
    <!-- Form content goes here --> 
<% } %> 

Khả năng này sẽ rất hữu ích trong bối cảnh của các chức năng Tôi đang cố gắng để tạo ra với các ví dụ trong this question

sẽ này cho tôi khả năng tạo vùng chứa cho các loại mà tôi sẽ là

<% 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> 

<% } %> 

Tôi nhận ra điều này sẽ tạo ra XHTML không hợp lệ, nhưng tôi nghĩ rằng có thể là những lợi ích khác lớn hơn điều này, đặc biệt là kể từ khi dự án này không yêu cầu XHTML xác nhận các tiêu chuẩn W3C.

Cảm ơn

Dave

Trả lời

14

Không khá chắc chắn có bao nhiêu giá trị này có hơn chỉ đơn giản là việc xác định một yếu tố <div>, nhưng một cái gì đó như vậy

/// <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; 
    } 
} 

và sử dụng như vậy

<% using (Html.BeginDiv(new Dictionary<string, object>{{"class","stripey"}})) 
{ %> 
     <p>Content Here</p> 
<% } %> 

sẽ hiển thị

<div class="stripey"> 
    <p>Content Here</p> 
</div> 

hoặc không có html thuộc tính

<% using (Html.BeginDiv()) 
{ %> 
     <p>Content Here</p> 
<% } %> 
+0

cảm ơn, tôi đã mất tích điều viewcontext.writer! – koenmetsu