2011-02-02 97 views
0

我已经为asp.net MVC构建了一个小型中继器HtmlHelper,我希望能够递归构建树型列表。因此,如果<T>有任何IEnumerable的孩子,我想将它们添加为嵌入式列表。ASP.NET MVC中继器帮助

这里是我有那么对于它创建了一个平坦的列表...

public static MvcHtmlString Repeater<T>(this HtmlHelper html, IEnumerable<T> items, 
     Func<T, HelperResult> itemTemplate,    
     Func<string, HelperResult> containerTemplate, 
     Func<string, HelperResult> emptyTemplate) 
    { 
     if (items == null) 
      return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(emptyTemplate("No Results").ToHtmlString())); 

     if (items.Count() == 0) 
      return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(emptyTemplate("No Results").ToHtmlString())); 

     StringBuilder sb = new StringBuilder(); 

     foreach (var item in items) 
     { 
      string content = itemTemplate(item).ToHtmlString(); 

      //Here I would want to append the children to 'content' using containerTemplate and itemTemplate.... 

      sb.Append(HttpContext.Current.Server.HtmlDecode(content)); 
     } 

     return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(containerTemplate(sb.ToString()).ToHtmlString())); 
    } 

任何帮助将不胜感激。

提前欢呼。

Gifster

回答

1

我会用递归来解决这个问题。我怀疑如果简单地将字符串附加到内容就足够了。您可能需要从模板中解析HTML,并以智能的方式将其插入到模板中,具体取决于它是列表还是表格等。我省略了该方法的实现,因为我不知道您期望如何它被使用。不过,我正在展示如何使用HtmlAgilityPack进行解析。

using HtmlAgilityPack; 

public static MvcHtmlString Repeater<T>(this HtmlHelper html, IEnumerable<T> items, 
    Func<T, HelperResult> itemTemplate,    
    Func<string, HelperResult> containerTemplate, 
    Func<string, HelperResult> emptyTemplate) 
{ 
    if (items == null) 
     return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(emptyTemplate("No Results").ToHtmlString())); 

    if (items.Count() == 0) 
     return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(emptyTemplate("No Results").ToHtmlString())); 

    StringBuilder sb = new StringBuilder(); 

    var enumerableProperties = typeof(T).GetProperties() 
             .Where(p => p is IEnumerable); 

    foreach (var item in items) 
    { 
     var doc = new HtmlDocument(); 
     doc.LoadHtml(itemTemplate(item).ToHtmlString()); 
     var root = doc.DocumentNode.FirstChild; 
     var insertNode = FindInsertNode(doc); // this needs to be written   
     foreach (var property in enumerableProperties) 
     { 
      var value = property.GetValue(item, null) as IEnumerable; 
      var newNode = new HtmlNode 
          { 
           InnerHtml = html.Repeater(value, itemTemplate, containerTemplate, emptyTemplate) 
          }; 
      root.InsertAfter(newNode, insertNode); 
      insertNode = newNode; 
     } 
     sb.Append(html.InnerText); 
    } 

    return MvcHtmlString.Create(HttpContext.Current.Server.HtmlDecode(containerTemplate(sb.ToString()).ToHtmlString())); 
} 
+0

谢谢,但它会被T的任何IEnumerable的孩子,但我想我将不得不去与此中继... – Andy 2011-02-02 19:47:01