我正在使用嵌套母版页。父级有一个菜单但是当我单击指向使用子级主页的页面的链接时,菜单为空,我收到错误。我通过创建一个查找菜单控件的递归方法来修复此问题,但现在它最终导航菜单上有两个相同的链接。有没有更好的方法呢?详情如下:
我有一个MainMaster页面,上面有一个菜单:
<%@ Master Language="VB" AutoEventWireup="false" CodeFile="Site.master.vb" Inherits="Site" %>
Code.....
<asp:Menu ID="NavigationMenu" RenderingMode="List" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal">
<Items>
<asp:MenuItem NavigateUrl="~/link1.aspx" Text="one"/>
<asp:MenuItem NavigateUrl="~/link2.aspx" Text="two"/>
</Items>
</asp:Menu>
<asp:ContentPlaceHolder ID="ContentPlaceHolder" runat="server"/>
嵌套在主要主人身上的ChildMaster:
<%@ Master Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="false" CodeFile="admin.master.vb" Inherits="admin" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Head" Runat="Server">
<asp:ContentPlaceHolder ID="Head" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder" Runat="Server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="false"/>
<asp:ContentPlaceHolder ID="ContentPlaceHolder" runat="server">
</asp:ContentPlaceHolder>
</div>
</asp:Content>
在MainMaster代码中,我需要查看登录用户是否为管理员。如果是,我需要添加一个指向管理页面的链接:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not (Page.IsPostBack) Then
Dim da As New Data
Dim user As Integer
user = Request.Cookies("userid").Value
If (da.isAdmin(user)) Then
Dim item As New MenuItem
item.Text = "Admin"
item.NavigateUrl = "~/Admin.aspx"
Dim menu As Menu
menu = FindControlRecursive("NavigationMenu")
menu.Items.Add(item)
End If
End If
End Sub
然而,当我点击Admin链接时,我会收到一条错误消息,指出Menu为null。我在这里找到了解决方案: Finding controls inside nested master pages
并使用此方法查找菜单控件(thankyou Niranjan Kala):
public static class PageExtensionMethods
{
public static Control FindControlRecursive(this Control ctrl, string controlID)
{
if (string.Compare(ctrl.ID, controlID, true) == 0)
{
// We found the control!
return ctrl;
}
else
{
// Recurse through ctrl's Controls collections
foreach (Control child in ctrl.Controls)
{
Control lookFor = FindControlRecursive(child, controlID);
if (lookFor != null)
return lookFor;
// We found the control
}
// If we reach here, control was not found
return null;
}
}
现在我可以点击管理员链接,菜单不再为空,但它会创建管理员链接的副本。我不明白为什么会这样,或者如何以不同的方式解决它。
编辑: 没关系。我是以错误的方式去做的。我通过在会话中存储菜单来修复它,然后如果菜单为空,我得到了我在会话中存储的原始菜单。我根本不需要递归函数来找到控件。
Session("menu") = NavigationMenu
If NavigationMenu Is Nothing Then
NavigationMenu = Session("menu")
Else
Dim data As New data
Dim user As Integer
user = Request.Cookies("userid").Value
If (data.isAdmin(uid)) Then
Dim item As New MenuItem
item.Text = "Admin"
item.NavigateUrl = "~/Admin.aspx"
NavigationMenu.Items.Add(item)
End If
End If