Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 视图中基于父子类的分层菜单_C#_Html_Asp.net Mvc 2 - Fatal编程技术网

C# 视图中基于父子类的分层菜单

C# 视图中基于父子类的分层菜单,c#,html,asp.net-mvc-2,C#,Html,Asp.net Mvc 2,我有一个ViewModel: public class Page { public int Id { get; set; } public Page Parent { get; set; } public string Name { get; set; } public string Title { get; set; } } 我正在将该模型传递给视图,我需要基于该模型创建一个层次菜单: <ul> <li>Page

我有一个ViewModel:

public class Page
{
    public int Id { get; set; }
    public Page Parent { get; set; }
    public string Name { get; set; }
    public string Title { get; set; }
}
我正在将该模型传递给视图,我需要基于该模型创建一个层次菜单:

<ul>
    <li>Page
        <ul>
            <li>Sub Page</li>
        </ul>
    </li>
  • 页面
    • 子页
通过不遗余力,我无法弄清楚如何在视图中执行这个递归循环

我可以在我的控制器中创建标记,但这不利于测试


有什么想法吗?

有很多方法可以显示动态生成的菜单,我会发布我的方法,我有两个类Menu&MenuItem(一个菜单只是一个MenuItem列表的包装器,它是实际的>“真实”链接),然后我有一个NavigationViewModel来包装所有内容

public class MenuItem
{
    public int MenuID { get; set; }
    public int ID { get; set; }
    public String Label { get; set; }
    public String Link { get; set; }
    public Boolean Show { get; set; }

    public MenuItem(int menuId, int id, string label, string link, Boolean show)
    {
        this.MenuID = menuId;
        this.ID = id;
        this.Label = label;
        this.Link = link;
        this.Show = show;
    }
}
public class NavigationModel
{
    public int currentMenuID { get; set; }   
    // used to determine the current displayed Menu to add
    // the "current" class to it. (to be set in the controller)

    public int currentMenuItemID { get; set; } 
    // used to determine the current displayed MenuItem to add
    // the "current" class to it. (to be set in the controller)

    public List<Menu> Menus { get; set; }


    public NavigationModel()
    {
        this.Menus = new List<Menu>();
        // Set Default Menu ( Menu 1 )
        this.currentMenuID = 1;
        // Set Default Menau Item ( None )
        this.currentMenuItemID = 0;
    }
}
//

//我有一个NavigationHelper,它负责使用以下两种方法输出HTML

注意:(这是一个简化版本,因为在我的实现中,我使用菜单和菜单项的id来定位正在显示的当前菜单,并向其中添加“当前”CSS类)

公共静态字符串显示菜单(此HtmlHelper帮助程序,NavigationModel navigationMenu)
{ 
公共静态字符串显示菜单(此HtmlHelper帮助程序,NavigationModel navigationMenu)
{            
字符串结果=“\n”;
返回结果;
}
私有静态字符串ConvertToItem(此HtmlHelper帮助程序,菜单项)
{
如果(项显示)
{
返回string.Format(“
  • \n”、helper.attributencode(item.Link)、helper.attributencode(item.Label)); } else{return”“;} } }
    最后,我在我的主菜单中有一个如下调用来显示菜单

    <!-- Navigation -->
    <%= Html.DisplayMenu(Model.NavigationMenu) %>
    
    
    
    注意:我有一个类型为(BaseViewModel)的强类型母版页,其中包含NavigationModel类型的属性NavigationMenu

    把一切联系在一起

    在我的示例中,我必须在每个操作方法中为视图提供一个ViewModel(继承我的BaseViewModel),然后构建菜单(使用一个生成器方法完成大部分工作,这样我就不必在每个操作方法中重新键入它)。如果不使用BaseViewModel,则需要找到另一种方法来构建导航模型,然后将导航模型传递到母版页


    对我来说,我发现有一个强类型母版页可以让事情变得更简单、更清晰。King wilder有一个很好的方法在他的母版页中实现它们。

    是因为我还是你的递归走错了方向?每个节点不应该有一个子节点列表,而不是每个节点都有一个父节点的引用吗?好的一点,这会让事情变得更容易,howe无论如何,它并没有完全回答我的问题……在使用ViewModel和生成分层菜单时,我仍然会遇到同样的问题。thanx对于这个广泛的示例,我不希望控制器或任何其他代码文件中有任何标记,我希望html标记中有某种递归循环。
    private static NavigationModel BuildNavigationMenu(User currentUser, string rootURL)
        {
            string loginURL = rootURL + "Account/LogOn";
    
            // Main Menu
            Menu MainMenu = new Menu(1, "Home");
            MainMenu.MenuItems.Add(new MenuItem(1, 1, "Welcome", rootURL, true));
            MainMenu.MenuItems.Add(new MenuItem(1, 2, "How It Works", rootURL + "Home/HowDoesItWork", true));
    
            // Work Menu
            Menu WorkMenu = new Menu(2, "Work");
            WorkMenu.MenuItems.Add(new MenuItem(2, 1, "Profile", rootURL + "User/Profile/" + currentUser.ID , true));
            WorkMenu.MenuItems.Add(new MenuItem(2, 2, "Customers", "#", true));
    
            // Add Menus To Navigation Model
            NavigationModel navigationMenu = new NavigationModel();
            navigationMenu.Menus.Add(MainMenu);
            navigationMenu.Menus.Add(HireMenu);
    
            return navigationMenu;
    }
    
    public static string DisplayMenu(this HtmlHelper helper, NavigationModel navigationMenu)
    { 
        public static string DisplayMenu(this HtmlHelper helper, NavigationModel navigationMenu)
        {            
            String result = "<ul id='main-nav'>\n";
            foreach(Menu menu in navigationMenu.Menus)
            {
                result +=     "<li>\n";
                result +=         string.Format("<a href='#'> {0} </a>\n",helper.AttributeEncode(menu.Name));
                result +=         "<ul>\n";
                foreach(MenuItem item in menu.MenuItems)
                {
                    result += NavigationHelper.ConvertToItem(helper, item);
                }
                result +=         "</ul>\n";
                result +=     "</li>\n";
            }
            result +=     "</ul>\n";
    
            return result;
        }
    
        private static string ConvertToItem(this HtmlHelper helper,MenuItem item)
        {
            if (item.Show)
            {
                return string.Format("<li><a href='{0}'>{1}</a></li>\n", helper.AttributeEncode(item.Link), helper.AttributeEncode(item.Label));
            }
            else { return ""; }   
        }
    }
    
    <!-- Navigation -->
    <%= Html.DisplayMenu(Model.NavigationMenu) %>