ASP.NET: Highlight menu item of current page - asp.net

I've been trying to find an easy way of highlighting the current selected menu item of an asp.net menu (so the user knows which page they are on), but no matter what I have tried I can't get it to work. In my markup I have:
<asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal" StaticSelectedStyle-ForeColor="#99CCFF" DynamicSelectedStyle-ForeColor="#99CCFF">
<Items>
<asp:MenuItem NavigateUrl="~/Default.aspx" Text="Operations"/>
<asp:MenuItem NavigateUrl="~/Analysis.aspx" Text="Analysis"/>
<asp:MenuItem NavigateUrl="~/Dashboard.aspx" Text="Dashboard"/>
<asp:MenuItem NavigateUrl="~/Flashboard.aspx" Text="Flashboard"/>
<asp:MenuItem NavigateUrl="~/Spacequest.aspx" Text="SQ OBP"/>
</Items>
</asp:Menu>
And in the server side Page_Load function:
((Menu)Master.FindControl("NavigationMenu")).Items[0].Selected = true;
But this does not work. I tried using a sitemap (even though a sitemap is not what I want to use) and that hasn't worked either. Any ideas?

There's a StaticSelectedStyle property that you can use inside your menu.
<asp:menu [...]>
<staticselectedstyle backcolor="LightBlue"
borderstyle="Solid"
bordercolor="Black"
borderwidth="1"/>
[...]
</asp:menu>
See here for more info.
Also, if there's a class applied to the selected item (which i'm not sure if there is but it would be handy) you can simply hook into that with your CSS. This would be a much nicer way than using the StaticSelectedStyle property.
UPDATE
It's worth noting also that your use of IncludeStyleBlock="false" will stop your menu from generating the CSS necessary to control the selected item.
With the style block turned off, you have to provide your own styles and the auto-generated styles of the menu will not be used.
From MSDN:
If you set this property to false, you cannot set style properties.
For example, you cannot add a DynamicHoverStyle-ForeColor attribute in
markup or set the DynamicHoverStyle.ForeColor property in code.
Source: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.menu.includestyleblock.aspx

I think you'll have to loop through the menu items and see if the current page URL contains the NavigateUrl of the menu item.
foreach (MenuItem item in mn.Items)
{
if (Request.Url.AbsoluteUri.ToLower().Contains(Page.ResolveUrl(item.NavigateUrl.ToLower()))
{
item.Selected = true;
}
}

I would use jQuery in this instance.
For the specified page, so for example on the Analysis.aspx page, add this bit of jquery to your page.
$('#MenuItemID').addClass('active');
Can you specify the ID of the menu items?
Such as:
<asp:MenuItem ID="AnalysisMenuItem" NavigateUrl="~/Analysis.aspx" Text="Analysis"/>
You would then use this:
$('#' + <% AnalysisMenuItem.ClientID %>').addClass('active');
then of course just define what active is in your css:
.active { background-color: #FFF; }

If you are thinking to make it dynamically, then this is the better way:
Menu MyMenu = new Menu();
....
MyMenu.MenuItemDataBound += new MenuEventHandler(MyMenu_MenuItemDataBound);
TheMenu.StaticSelectedStyle.CssClass ="MySelectedClass";
protected void MyMenu_MenuItemDataBound(Object sender, MenuEventArgs e)
{
if (e.Item.NavigateUrl.ToLower().Contains(Path.GetFileName(Request.FilePath).ToLower()))
{
//e.Item.Text = "<div style='color: Yellow'>" + e.Item.Text + " </div>";
e.Item.Selected = true;
}
}
add then simply add .MySelectedClass style to your Css file
..

//Master
<asp:Menu ID="NavigationMenu" runat="server" CssClass="menu"
EnableViewState="False" Orientation="Horizontal"
BackColor="#465C71" DynamicHorizontalOffset="2"
ForeColor="#DDE4EC">
<StaticMenuItemStyle HorizontalPadding="15px" VerticalPadding="2px" />
<StaticSelectedStyle BackColor="#FFFFFF" ForeColor="#000000"/>
<Items>
<asp:MenuItem NavigateUrl="~/Secure/About.aspx" Text="About"/>
<asp:MenuItem NavigateUrl="~/Secure/Login.aspx" Text="Login"/>
</Items>
</asp:Menu>
//Master.cs
foreach (MenuItem item in ((Menu)this.FindControl("NavigationMenu")).Items)
{
if(Request.Url.AbsoluteUri.ToLower().Contains(item.NavigateUrl.ToLower().Substring(1)))
{
item.Selected = true;
}
}
//item.NavigateUrl.ToLower() contains "~". So, find substring and check.

Related

ASP.NET Menu Control in Master page - Hilight selected menu item

I know this has been asked, and answered before, but I still can't get it to work. And I've boiled it down to this. If I specify a NavigateURL in a MenuItem, it does not work. If I don't, the menu item changes its style as expected when clicked. However, it is completely useless as a navigation menu, since it no longer takes you anywhere! :)
So to clarify, this works - selected item is hilighted as per specified style:
<asp:menu id="NavigationMenu" staticdisplaylevels="1" orientation="Horizontal" runat="server">
<staticselectedstyle backcolor="LightBlue" borderstyle="Solid" bordercolor="Black" borderwidth="1"/>
<items>
<asp:MenuItem Text="Home" Value="Home" />
<asp:MenuItem Text="Software" Value="Software" />
</items>
</asp:menu>
And this doesn't work - only change is adding NavigateURLs:
<asp:menu id="NavigationMenu" staticdisplaylevels="1" orientation="Horizontal" runat="server">
<staticselectedstyle backcolor="LightBlue" borderstyle="Solid" bordercolor="Black" borderwidth="1"/>
<items>
<asp:MenuItem NavigateUrl="/Default.aspx" Text="Home" Value="Home" />
<asp:MenuItem NavigateUrl="/Software.aspx" Text="Software" Value="Software" />
</items>
</asp:menu>
In this other post, the OP is using NavigateURLs, and has accepted the answer about StaticSelectedStyle. I don't get it.
I would like to understand how to keep the StaticSelectedStyle working, and use NavigateURLs, at the same time.
I should add that the menu is in the master page. The pages being navigated to use this master page.
Thanks!
-Sandra
EDIT:
Based on my reading on this topic, I think this doesn't work because the Menu control only knows where it is on a Postback. But if your menu item takes you to some other page, it is no longer a postback, and the menu control is loaded afresh and does not know which item was clicked.
Try adding some code to the Page_Load section of your master file to bounce the page name from the url against the NaviagteUrl from your menu item. Here:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
For Each item As MenuItem In NavigationMenu.Items
If Request.Url.AbsoluteUri.ToLower().Contains(Page.ResolveUrl(item.NavigateUrl.ToLower())) Then
item.Selected = True
End If
Next
End Sub
That is in VB.NET. It works, I tested it using your markup from above. I hope you can figure out how to fit that into your code.

asp.net how to change visibility of a menu item from load function in .cs

<div id = "menu2" style ="position:absolute;right:400px; margin-top: -55px;">
<asp:Menu ID="Menu2" runat="server" Height="16px" style="margin-left: 1125px"
Width="63px" Visible="False">
<Items>
<asp:MenuItem Text="Economics" Value="Economics" ImageUrl="~/images/dollar.png"></asp:MenuItem>
</Items>
</asp:Menu> </div>
The above code is located in .aspx page. In the load function in the .cs file , how can I change the visibility of this menu?
I can change the NavigationUrl via the following statement
Menu1.Items[0].NavigateUrl = AfeAttachment;
but I can't seem to adjust the visibility
Paste the following the code into the method you're using to change the menu's visibile attribute:
Menu2.Visible = true;

Set CSS class 'selected' in ASP.NET menu parents and their children?

I have the following menu control embedded in the Site.master file:
<asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal" RenderingMode="List">
<Items>
<asp:MenuItem NavigateUrl="~/Default.aspx" Text="Home" />
<asp:MenuItem NavigateUrl="~/TechServices.aspx" Text="Tech Services"/>
<asp:MenuItem NavigateUrl="~/HumanResources.aspx" Text="Human Resources"/>
<asp:MenuItem NavigateUrl="~/Marketing.aspx" Text="Marketing"/>
<asp:MenuItem NavigateUrl="~/DocumentControl.aspx" Text="Document Control"/>
<asp:MenuItem NavigateUrl="~/IT.aspx" Text="Information Tech"/>
</Items>
</asp:Menu>
In order to set the CSS class attribute selected I use the following C# code:
protected void Page_Load(object sender, EventArgs e) {
string thispage = this.Page.AppRelativeVirtualPath;
int slashpos = thispage.LastIndexOf('/');
string pagename = thispage.Substring(slashpos + 1);
foreach (MenuItem mi in NavigationMenu.Items) {
if (mi.NavigateUrl.Contains(pagename)) {
mi.Selected = true;
break;
}
}
}
The code above works great. However, these pages now contain sub-pages (children) and I would like to parent pages retain their "Selected" CSS attribute when accessing one of their children pages.
I also created the Web.sitemap file to organize all the parent and their children pages. However, I am stock on how to use the Web.sitemap to help the C# function above to help the parent menu retain their CSS class "selected" attribute. I am not sure if I need the Web.sitemap file for this purpose? The parent and child logic is only available in the Web.sitemap file.
Once you find the MenuItem to select just traverse upward and select all parent. Here's some pseudo-code:
MenuItem miP = mi.Parent;
while (miP != null)
{
miP.Selected = true;
if (miP.Parent == null)
break;
else
miP = miP.Parent;
}

ASP.NET Menu Image with Dropdown Text Subitems

I have a menu user control with image buttons like this one:
<asp:TableCell ID="tcDownload" runat="server" CssClass="MyMenuTableCellDownload" VerticalAlign="Top" >
<asp:ImageButton ID="ibtnDownload" runat="server" ImageUrl="~/Images/MyMenu/tb_download_1.gif"
CssClass="MyMenuIbtn" ToolTip="Download Results" />
</asp:TableCell>
In the codebehind, I handle the onclick for these to navigate to another page:
ibtnDownload.Attributes.Add("onclick", "document.location.href = '" + strNavUrl + "';return false");
Elsewhere in the user control, I have regular text menus like this one:
<asp:TableCell ID="tcMyMenuCust" runat="server">
<asp:Menu ID="menuMyCust" runat="server" StaticDisplayLevels="1" MaximumDynamicDisplayLevels="1" Orientation="Horizontal"
CssClass="MyMenuCustomer" StaticMenuItemStyle-ItemSpacing="0px" DynamicMenuItemStyle-CssClass="MyMenuDynamicItem"
StaticMenuItemStyle-CssClass="MyMenuStaticItem" DynamicHoverStyle-CssClass="MyMenuDynamicItemHover" DynamicVerticalOffset="0"
StaticHoverStyle-CssClass="MyMenuStaticItemHoverCust" StaticEnableDefaultPopOutImage="false"
DynamicPopOutImageUrl="~/Images/MyMenu/menu_arrow_grey.gif" DynamicMenuItemStyle-VerticalPadding="2"
DisappearAfter="0" OnMenuItemClick="menuMy_MenuItemClick">
<Items>
<asp:MenuItem Text="Customers" ImageUrl="~/Images/MyMenu/MyMenuGradientTransparent.png" Selectable="false">
<asp:MenuItem Text="Domestic "
Value="Customer_Domestic",
NavigateUrl="~/MyMain.aspx?_page=DomCusts&_title=DomesticCustomers">
</asp:MenuItem>
<asp:MenuItem Text="International "
Value="Customer_International"
NavigateUrl="~/MyMain.aspx?_page=IndCusts&_title=InternationalCustomers">
</asp:MenuItem>
</asp:MenuItem>
</Items>
</asp:Menu>
</asp:TableCell>
What I want to do is extend the menu choices by changing the image buttons to behave like the regular menus, while maintaining their look (image resource). That is, clicking on the image should result in a submenu dropping down to display subitems.
I know it's possible to use properties such as StaticEnableDefaultPopOutImage to indicate that a menu item has child items. I also understand that menu items can have background images, but what if I simply want to use an image rather than text on a main menu item that drops down subitems when clicked?
This turns out to be fairly straightforward. In the example above, I provide an ID for the top level item ("Customers") and remove the Text property, so that only the image refferred to in the ImageURL appears.

ASP.Net Master Page Sidebar display after Login (keeping it displayed whilst logged in)

I have the following sidebar on my master page. It is not a part of any ContentPlaceHolder.
<div runat="server" visible="false" id="menuAccountMembersDiv" class="leftCol">
<asp:Menu ID="menuAccountMembers" runat="server" StaticSubMenuIndent="16px" Visible="false">
<Items>
<asp:MenuItem ImageUrl="~/Resources/x.png"
NavigateUrl="~/About.aspx" Text="x" ToolTip="x"
Value="b647ce4e-5c7f-400c-a921-ec7902494f26"></asp:MenuItem>
<asp:MenuItem ImageUrl="~/Resources/y.png"
NavigateUrl="~/About.aspx" Text="y" ToolTip="y"
Value="y"></asp:MenuItem>
<asp:MenuItem ImageUrl="~/Resources/sarahhunkin.png" NavigateUrl="~/About.aspx"
PopOutImageUrl="~/Resources/z.png" Text="z"
ToolTip="z" Value="z"></asp:MenuItem>
<asp:MenuItem ImageUrl="~/Resources/a.png"
NavigateUrl="~/About.aspx"
PopOutImageUrl="~/Resources/apop.png" Text="a"
ToolTip="a" Value="a"></asp:MenuItem>
</Items>
</asp:Menu>
</div>
I initially hide it. But I would like to display it and keep it displayed after logging in. Using the standard web application login page. I tried the following:
protected void LoginUser_LoggedIn(object sender, EventArgs e)
{
Menu MenuAccountMembers = (Menu)Master.FindControl("menuAccountMembers");
MenuAccountMembers.Visible = true;
Control menuAccountMembersDiv = (Control)Master.FindControl("menuAccountMembersDiv");
menuAccountMembersDiv.Visible = true;
}
I am not sure to to interact with the div tag, as there is no Div object. In any event, this does not display the sidebar with the menu
EDIT:
I ended up adding the following code to the master page itself.
public partial class SiteMaster : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (HttpContext.Current.Request.IsAuthenticated)
{
Control MenuDiv = this.FindControl("menuAccountMembersDiv");
MenuDiv.Visible = true;
Menu AccountMenu = (Menu)MenuDiv.FindControl("menuAccountMembers");
AccountMenu.Visible = true;
}
}
}
I would go for setting the visibiliy directly on your div based on authentication status
<div runat="server" visible="<%# Page.User.IsAuthenticated %>" id="menuAccountMembersDiv" class="leftCol">
that way you don't need your LoginUser_LoggedIn method and the menu will show/hide on every load depending on the user is logged in or not
And remember to remove the Visible="false" from your <asp:Menu> control, if the outer div is hidden, nothing inside it will be shown anyway.
Since you have the runat="server" tag in the menu's Div tag, you can reference it directly in code...
menuAccountMembersDiv.Style.Item("Display") = "none";
or
menuAccountMembersDiv.Visible = False;
A div tag is a HtmlGenericControl class. To get access to this class import namespace System.Web.UI.HtmlControls; and use something like this:
HtmlGenericControl div = Master.FindControl("menuAccountMembersDiv") as HtmlGenericControl;
if(div != null)
{
div.Visible = true;
}
Or you can move your menu to UserControl and hide or show just use ID of your UserControl.
Hope it will help you with your question.

Resources