我正在使用嵌套母版页。父级有一个菜单,但是当我单击指向使用子级主控的页面的链接时,菜单为空,并且出现错误。我通过创建一个找到菜单控件的递归方法来解决这个问题,但现在它在导航菜单上出现了两个相同的链接。有没有更好的方法来做到这一点?详情如下:
我有一个带有菜单的 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
但是,当我单击管理员链接时,我会收到一条错误消息,提示菜单为空。我在这里找到了解决方案: 在嵌套母版页中查找控件
并使用此方法找到菜单控件(谢谢 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