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

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.

Related

.NET 4.5: ASP Menu Item value displaying as a link?

In my code below the asp menu item value property is actually rendering as link text!
<asp:Menu ID="menuTop" runat="server" EnableViewState="true" Orientation="Horizontal" StaticSelectedStyle-CssClass="menuselected" SkipLinkText="">
<Items>
<asp:MenuItem NavigateUrl="~/Default.aspx" ImageUrl="~/images/Menu_Home.jpg" Value="Home" />
<asp:MenuItem NavigateUrl="~/Contact.aspx" ImageUrl="~/images/Menu_Contact.jpg" Value="Contact"/>
</Items>
</asp:Menu>
According to the MSDN reference located at http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.menuitem.value.aspx
The Value property is used to supplement the Text property by storing
any additional data associated with the menu item. This value is not
displayed in the control and is commonly used to store data for
handling postback events.
I need it to store values, why is it displaying as link text?
Try this code.
<asp:Menu ID="menuTop" runat="server" EnableViewState="true" Orientation="Horizontal" StaticSelectedStyle-CssClass="menuselected" SkipLinkText="">
<Items>
<asp:MenuItem NavigateUrl="~/Default.aspx" ImageUrl="~/images/Menu_Home.jpg" Value="Home" Text="" />
<asp:MenuItem NavigateUrl="~/Contact.aspx" ImageUrl="~/images/Menu_Contact.jpg" Value="Contact" Text=""/>
</Items>
</asp:Menu>
Nevermind, I figured it out. Looks like you need to set the Text value to "" and that prevents the value from displaying as text.

Preventing page refresh when handling MenuItemClick at server

I have a menu item that when clicked is calling a C# codebehind function.
The function doesn't get called and the whole page get refreshed.
In aspx:
<asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal" onmenuitemclick="NavigationMenu_MenuItemClick">
<Items>
<asp:MenuItem Text="Item caption" Value="#" />
</Items>
</asp:Menu>
In C#:
protected void NavigationMenu_MenuItemClick(object sender, MenuEventArgs e)
{
Response.Redirect("");
SomeFunction();
}
If I'm removing the Redirect call, the page get refresh and looks like a mess.
Any advice will be welcome.
To get a better answer, you many want to edit your question to better explain what you are trying to accomplish.
The Menu control without the NavigateUrl attribute emits HTML that includes a list (of your menu items) with hyperlinks that perform a postback via some Javascript.
<ul class="level1">
<li>
<a class="level1selected" href="#"
onclick="__doPostBack('ctl00$MainContent$NavigationMenu','#')">
Item caption</a>
</li>
</ul>
When handling the menu click event, if your intent is to redirect the user to another page I would recommend simply setting the NavigateUrl attribute on your menu items instead of using Response.Redirect().
<asp:MenuItem Text="Item caption" Value="#" NavigateUrl="~/TargetPage.aspx" />
If you set the NavigateUrl attribute, you'll notice the onclick event doesn't even get added to the anchor tags that make up the menu item's HTML.
<ul class="level1">
<li>
<a class="level1" href="TargetPage.aspx">Item caption</a>
</li>
</ul>
If you're not intending to use the menu for navigation, but rather to perform some logic and update the page when the menu item is clicked, you may consider putting your menu in an UpdatePanel and set up the menu to trigger an async postback.
ASPX:
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="NavigationMenu" />
</Triggers>
<ContentTemplate>
<asp:Label ID="label1" runat="server"></asp:Label>
<asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="true" IncludeStyleBlock="false" Orientation="Horizontal" onmenuitemclick="NavigationMenu_MenuItemClick">
<Items>
<asp:MenuItem Text="Item caption" Value="#" />
</Items>
</asp:Menu>
</ContentTemplate>
</asp:UpdatePanel>
Code Behind:
protected void NavigationMenu_MenuItemClick(object sender, MenuEventArgs e)
{
SomeFunction();
}
private void SomeFunction()
{
//Performed some logic
label1.Text = "Altered the page on menu item click";
}

ASP.NET: Highlight menu item of current page

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.

change a specific Picture in menu

Hi If any of you know how to change a specific Picture on ohver at menuItem in menu control
the code is like this
<asp:Menu ID="NavigationMenu" runat="server" CssClass="menu"
EnableViewState="False" IncludeStyleBlock="False">
<Items>
<asp:MenuItem NavigateUrl="~/Homepage.aspx" ImageUrl="~/images/ONE.png" ></asp:MenuItem>
<asp:MenuItem NavigateUrl="~/AboutUs.aspx" ImageUrl="~/images/SOME.png"></asp:MenuItem>
<asp:MenuItem NavigateUrl="~/ContactUs.aspx" ImageUrl="~/images/MENU.png"></asp:MenuItem>
</Items>
</asp:Menu>
Please show an example, thanks Please ,Please,Please,Please, I need it
You Looking to change this in the page code behind, and when are you trying to do this, on mouse hover or..?
If done in code behind:
NavigationMenu.Items[0].ImageUrl = "whatever.jpg";

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.

Resources