2009-09-08 4 views
2

C#을 사용하여 재귀 HTML 메뉴를 만들려고합니다. 필요한 html 구조는 다음과 같습니다.C와 재귀 메뉴 작성기 #

<ul> 
    <li>Office</li> 
    <li>Home 
     <ul> 
     <li>Beds</li> 
     <li>Desks</li> 
     </ul> 
    </li> 
    <li>Outdoor 
     <ul> 
     <li>Children 
      <ul> 
       <li>Playsets</li> 
      </ul> 
     </li> 
     </ul> 
    </li> 
</ul> 

구조가 동적 인 것처럼 분명히 변경 될 수 있습니다. 현재로서는 HtmlGeneric 컨트롤 (예 : ul, li 및 컨트롤 추가)을 사용하고 있지만이를 효율적인 재귀 함수로 바꾸는 방법을 모르겠습니다.

+0

mo에있는 코드를 추가하십시오. – Owen

+1

문자열 (예 : '집', '침대', '책상'등)을 유지하기 위해 사용하는 구조는 무엇입니까? – link664

답변

3

문자열 계층 구조를 유지하는 구조가 무엇인지 확실하지 않지만 필요한 경우 각 문자열의 자식 문자열을 가져 오는 방법이 있다고 가정 해 봅시다 (예 : '침대'및 '데스크'를 가져올 수 있음) '집').

public const string OPEN_LIST_TAG = "<ul>"; 
public const string CLOSE_LIST_TAG = "</ul>"; 
public const string OPEN_LIST_ITEM_TAG = "<li>"; 
public const string CLOSE_LIST_ITEM_TAG = "</li>"; 

가 그럼 난 스트링 빌더 같은 것을 사용하여 재귀 적 방법을 만들 것입니다 :

우선은 상수로 태그를 선언 할

/// <summary> 
/// Adds another level of HTML list and list items to a string 
/// </summary> 
/// <param name="str">The string to add</param> 
/// <param name="liStrings">The list of strings at this level to add</param> 
/// <param name="iTabIndex">The current number of tabs indented from the left</param> 
public void GenerateHTML(System.Text.StringBuilder str, List<string> liStrings, int iTabIndex) { 
    //add tabs to start of string 
    this.AddTabs(str, iTabIndex); 

    //append opening list tag 
    str.AppendLine(OPEN_LIST_TAG); 

    foreach (string strParent in liStrings) { 
     //add tabs for list item 
     this.AddTabs(str, iTabIndex + 1); 

     //if there are child strings for this string then loop through them recursively 
     if (this.GetChildStrings(strParent).Count > 0) { 
     str.AppendLine(OPEN_LIST_ITEM_TAG + strParent); 
     GenerateHTML(str, this.GetChildStrings(strParent), iTabIndex + 2); 

     //add tabs for closing list item tag 
     this.AddTabs(str, iTabIndex + 1); 
     str.AppendLine(CLOSE_LIST_ITEM_TAG); 
     } 
     else { 
     //append opening and closing list item tags 
     str.AppendLine(OPEN_LIST_ITEM_TAG + strParent + CLOSE_LIST_ITEM_TAG); 
     } 
    } 

    //add tabs for closing list tag 
    this.AddTabs(str, iTabIndex); 
    //append closing list tag 
    str.AppendLine(CLOSE_LIST_TAG); 
} 

그리고 별도로 추가 탭을 분리 방법 :

/// <summary> 
/// Appends a number of tabs to the string builder 
/// </summary> 
/// <param name="str">The string builder to append to</param> 
/// <param name="iTabIndex">The number of tabs to append to</param> 
public void AddTabs(System.Text.StringBuilder str, int iTabIndex) { 
    for (int i = 0; i <= iTabIndex; i++) { 
     str.Append("\t"); 
    } 
} 

다음은 새로운 문자열 작성기로 GenerateHTML을 호출하기 만하면됩니다. 문자열의 첫 번째 수준 및 탭 인덱스를 0으로 설정하고 원하는 것을 제공해야합니다. 어떤 종류의 구조를 사용하고 있는지 확실하지 않았기 때문에 하위 문자열을 가져 오는 기능을 포함하지 않았습니다. 저에게 알려 주시면 솔루션을 적용 할 수 있습니다.

호프가 도움이 되었으면 데인.

0

그런 목록에 관한 유일한 재귀는 데이터의 srt 구조입니다. NGenerics은 좋은 오픈 소스 자료 구조 라이브러리입니다.

또한이 문제에서 HTMLTextWriter Class을 사용하는 것이 좋습니다.

롤 - 자신 - 자신의 접근 방식을 취하고 서버 컨트롤을 만들려면 아래 클래스와 같은 것이 작동합니다.

public class MenuTree : Control 
{ 
    public string MenuText {get; set;} 
    public List<MenuTree> Children {get; set;} 

    public override void Render(HTMLTextWriter writer) 
    { 
     writer.RenderBeginTag(HtmlTextWriterTag.Ul); 
     writer.RenderBeginTag(HtmlTextWriterTag.Li); 
     writer.RenderBeginTag(MenuText); 
     writer.RenderEndTag(); 
     foreach (MenuTree m in Children) 
     { 
     m.Render(); 
     } 
     writer.RenderEndTag(); 
    } 


} 
1

약간 오래된 주제 그럼에도 불구하고 그것이 정답 내 예에서

을 가져야한다 들어오는 노드는 자식 요소를 포함하는 어린이 속성이 포함되어 있습니다.

private HtmlGenericControl RenderMenu(Nodes nodes) 
{ 
    if (nodes == null) 
     return null; 

    var ul = new HtmlGenericControl("ul"); 

    foreach (Node node in nodes) 
    { 
     var li = new HtmlGenericControl("li"); 
     li.InnerText = node.Name; 

     if(node.Children != null) 
     { 
      li.Controls.Add(RenderMenu(node.Children)); 
     } 

     ul.Controls.Add(li); 
    } 

    return ul; 
} 
+0

우수. 나는 그런 것을보고있다. – Nakres