ネストされたマスター ページを使用しています。親にはメニューがありますが、子マスターを使用するページへのリンクをクリックすると、メニューが null になり、エラーが発生します。メニュー コントロールを見つける再帰的なメソッドを作成することでこれを修正しましたが、ナビゲーション メニューに 2 つの同じリンクが表示されるようになりました。これを行うより良い方法はありますか?以下の詳細:
メニューのある 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
しかし、管理リンクをクリックすると、メニューが null であるというエラーが表示されました。ここでこれに対する解決策を見つけました: ネストされたマスターページ内のコントロールの検索
そして、このメソッドを使用してメニュー コントロールを見つけました (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;
}
}
これで管理者リンクをクリックできるようになり、メニューは null ではなくなりましたが、管理者リンクの複製が作成されます。これがなぜなのか、またはこれを別の方法で修正する方法がわかりません。
編集:気にしないでください。私はそれについて間違った方法で行っていました。メニューをセッションに保存することで修正しました。メニューが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