C# 使用c语言的递归菜单生成器#
尝试使用c#构建递归html菜单。我需要的html结构如下所示:C# 使用c语言的递归菜单生成器#,c#,recursion,C#,Recursion,尝试使用c#构建递归html菜单。我需要的html结构如下所示: <ul> <li>Office</li> <li>Home <ul> <li>Beds</li> <li>Desks</li> </ul> </li> <li>Outdoor <ul>
<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和添加控件,但不确定如何将其转换为有效的递归函数。我不确定保持字符串层次结构的结构是什么,但假设您有某种方法可以根据需要获取每个字符串的子字符串(例如,您可以从“家”获得“床”和“桌子”) 首先,我将标记声明为常量:
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>";
public const string OPEN_LIST_TAG=“”;
public const string CLOSE_LIST_TAG=“
”;
public const string OPEN_LIST_ITEM_TAG=“”;
public const string CLOSE_LIST_ITEM_TAG=“ ”;
然后,我将使用类似字符串生成器的东西创建一个递归方法:
/// <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);
}
//
///将另一级别的HTML列表和列表项添加到字符串中
///
///要添加的字符串
///此级别要添加的字符串列表
///从左侧缩进的当前选项卡数
public void GenerateHTML(System.Text.StringBuilder str,List liStrings,int-iTabIndex){
//将选项卡添加到字符串的开头
这是AddTabs(str,iTabIndex);
//附加开始列表标记
str.AppendLine(打开列表标签);
foreach(liStrings中的字符串strParent){
//为列表项添加选项卡
这个.AddTabs(str,iTabIndex+1);
//如果此字符串有子字符串,则递归地遍历它们
if(this.GetChildStrings(strParent.Count>0){
str.AppendLine(打开列表项标记+strParent);
GenerateHTML(str,this.GetChildStrings(strParent),iTabIndex+2);
//为关闭列表项标记添加选项卡
这个.AddTabs(str,iTabIndex+1);
str.AppendLine(关闭列表项标记);
}
否则{
//附加开始和结束列表项标记
str.AppendLine(打开列表项标记+strParent+关闭列表项标记);
}
}
//为关闭列表标记添加选项卡
这是AddTabs(str,iTabIndex);
//附加结束列表标记
str.AppendLine(关闭列表标签);
}
并将选项卡分离出来,添加到单独的方法中:
/// <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");
}
}
//
///将多个选项卡附加到字符串生成器
///
///要附加到的字符串生成器
///要附加到的选项卡数
public void AddTabs(System.Text.StringBuilder str,int-iTabIndex){
对于(inti=0;i这样的列表,唯一递归的是数据结构,这是一个很好的数据结构开源库
另外,我建议在这个问题中使用
如果您想采用自己的方法创建一个服务器控件,那么下面的类就可以了
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();
}
}
公共类菜单ree:Control
{
公共字符串MenuText{get;set;}
公共列表子项{get;set;}
公共覆盖无效呈现(HTMLTextWriter)
{
writer.RenderBeginTag(htmltextwittertag.Ul);
writer.RenderBeginTag(htmltextwittertag.Li);
writer.RenderBeginTag(MenuText);
writer.renderndtag();
foreach(儿童的MenuTree m)
{
m、 Render();
}
writer.renderndtag();
}
}
这个话题有点老,但它应该有一个正确的答案
在我的示例中,传入节点包含一个包含子元素的子属性
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;
}
请添加任务单上的代码。您使用什么结构来保存字符串(即“家”、“床”、“桌子”等)?