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

2024-03-29

我有一个视图模型:

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 (菜单只是 MenuItems 列表的包装,MenuItems 是实际的>“真实”链接),然后我有一个 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 Menu
{
    public int ID { get; set; }
    public string Name { get; set; }
    public List<MenuItem> MenuItems { get; set; }

    public Menu(int id, string name)
    {
        this.ID = id;
        this.Name = name;
        this.MenuItems = new List<MenuItem>();
    }

}

// 这是包装所有内容的 NavigationModel。

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

// 这是构建 NavigationModel 的方法示例。

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

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

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

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

最后,我在 Master 中进行了以下调用来显示菜单。

<!-- Navigation -->
<%= Html.DisplayMenu(Model.NavigationMenu) %>

注意:我有一个强类型的 MasterPage,其类型 (BaseViewModel) 包含 NavigationModel 类型的属性 NavigationMenu

将一切连接在一起。

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

对我来说,我发现有一个强类型的 MasterPage 可以让事情变得更简单、更干净。怀尔德王有一个很好的方法来在他的高尔夫追踪器系列 http://www.mvccentral.net/Article/Details/3/Golf_Tracker_-_Pt_1_-_Overview.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于父子类的视图中的分层菜单 的相关文章

  • 如何以编程方式确定 C 中 int 数据的最大和最小限制?

    我正在尝试 K R 的练习 2 1 练习内容如下 编写一个程序来确定范围char short int and long变量 两者signed and unsigned 通过从标准标题打印适当的值并通过直接计算 如果计算它们会更困难 确定各种
  • 尝试将元素推入向量

    在头文件 我没有编写 中 已经定义了一个结构体 如下所示 struct MemoryMessage public boost counted base public FastAlloc explicit MemoryMessage Memo
  • 在 C 程序中追踪数组越界访问/写入的推荐方法

    考虑用 C 语言编写一些不太明显的算法的实现 例如 让它成为递归快速排序 我在 K N King 的 C 编程 现代方法 第二版 书中找到了它 可以从here http knking com books c2 programs qsort
  • 使用 Thread.Sleep() 时,异步编程如何与线程一起工作?

    假设 前言 在之前的问题中 我们注意到Thread Sleep阻塞线程参见 什么时候使用Task Delay 什么时候使用Thread Sleep https stackoverflow com questions 20082221 whe
  • c#Registry to XML无效字符问题

    我在尝试从注册表创建 XML 文件时遇到问题 在我的笔记本电脑 W7 64b 上它工作正常 生成了 xml 文件 但在另一台计算机 Xp 32b 上抛出异常 System ArgumentException 十六进制值 0x00 是无效字符
  • 是否可以用 C# 为 Android 编写应用程序?

    我们都知道Android运行Dalvik VM程序 通常开发人员用 Java 编写程序并将其编译为 Dalvik 字节码 我想知道是否有可能创建一个可以接受 C 代码并将其编译为 Dalvik 字节码的编译器 嗯 这是一种选择 或者您可以在
  • C++ 克隆惯用语中协变返回类型的用处?

    通常的克隆习惯使用协变返回类型 struct Base virtual Base clone struct Derived public Base Derived clone 我读过一些内容 大意是协变返回类型是 C 后来添加的 较旧的编译
  • 平衡两轮机器人而不使其向前/向后漂移

    我正在尝试设计一个控制器来平衡 2 轮机器人 约 13 公斤 并使其能够抵抗外力 例如 如果有人踢它 它不应该掉落 也不应该无限期地向前 向后漂移 我对大多数控制技术 LQR 滑模控制 PID 等 都很有经验 但我在网上看到大多数人使用 L
  • 发生错误。", ExceptionMessage: "提供的 'HttpContent' 实例无效

    尝试将文件添加到 http 休息调用时出现此错误 responseJson 消息 发生错误 ExceptionMessage 提供了无效的 HttpContent 实例 它确实 正在使用 多部分 参数名称 内容 异常类型 System Ar
  • 如何在 ASP.NET MVC 2.0 中的视图之外创建 HtmlHelper?

    我们正在将 ASP NET MVC 1 0 应用程序升级到 2 0 版本 部分代码需要使用 LinkExtensions 而 LinkExtensions 需要 HtmlHelper 才能呈现 虽然我们知道某些代码没有正确遵循 MVC 模型
  • Parallel.For 和 Break() 误解?

    我正在研究 For 循环中的并行性中断 看完之后this http tipsandtricks runicsoft com CSharp ParallelClass html and this http reedcopsey com 201
  • 在 C# 中加密并在 Flex 中解密

    我需要解密 Flex 中的一些数据 这些数据是用 C 加密并写入文件的 为了简单起见 我选择使用 as3crypto As3 库和 Bruce Schneier C 库 AS3 as3加密链接 http code google com p
  • 无论表单上的焦点控件如何,如何捕获 Keys.F1?

    我使用了 KeyDown 事件和一些简单的代码 例如if e KeyCode Keys F1 捕获在表单上按下 F1 但如果表单上有一些文本框 或者表单上有一些带有 Dock Fill 的电子表格 则上面的代码将毫无用处并且不执行任何操作
  • Yield Return == IEnumerable 和 IEnumerator 吗?

    Is yield return实施的捷径IEnumerable and IEnumerator 是的 您可以在我的书 C in Depth 的第 6 章中找到更多相关信息 幸好第六章是免费提供 http www manning source
  • 在 C# 中将 ulong 映射到 long ?

    我正在尝试将 ulong 映射到 long 反之亦然 将 uint 映射到 int 反之亦然 如下所示 为了将值保存在具有签名类型的 MS SQL 数据库中仅限整数和大整数 我这样做是因为我必须检查 在数据库中 一个数字 uint ulon
  • lambda 表达式是多线程的吗?

    lambda 表达式是多线程的吗 假设当你将数学公式编写为 lambda 方法时 当你将其传递给另一个方法时 它会是多线程的吗 不是100 清楚你问的是什么 您是否想问 lambda 是否自然地在不同的线程上运行 如果是这样 则它们只是 S
  • 可以在 IE 中的表格行上添加渐变吗?

    当我将鼠标悬停在表格特定部分的表格行上时 我希望背景更改为线性渐变 CSS 很简单 tbody row links tr hover background typical multi browser linear gradient code
  • 使用 LINQ to SQL 的 .NET 架构的最佳设计实践(DAL 必要吗?我们真的可以使用 POCO吗?要采用的设计模式吗?)

    我避免在 net arch n 层架构上编写看起来像是另一个线程的内容 但请耐心等待 希望我和其他人一样 在选择用于企业应用程序的架构时 考虑到当今的趋势和新兴技术 仍然没有 100 满意或不清楚应采取的最佳方法 我想我正在寻求大众社区对方
  • 复选标记的 HTML 实体[重​​复]

    这个问题在这里已经有答案了 是否有用于复选标记的 HTML 实体 我在各种 html 实体备忘单中搜索过它 但没有找到 像这样的东西吗 如果是这样 请输入 HTML 10004 And 10003 给出一个更轻的
  • 在 WPF 树视图中获取 FullPath?

    如果我以编程方式创建 WPF TreeView 例如 TreeView treeView lt added in the designer TreeViewItem rootNode new TreeViewItem rootNode He

随机推荐