views:

4862

answers:

3

I'm hoping to use an ASP.NET Menu Control for navigation through my site. However, I've got a requirement that each MenuItem must be styled differently (different colors, both static, and onHover). Without creating a custom class that would inherit from MenuItem, is this possible?

Thoughts on a better solution?

A: 

If you generate the menu programmatically, you can add the style and onmouseover/onmouseout attributes when creating each MenuItem, e.g.:

menuItem.Attributes["style"] = "color: red;";
menuItem.Attributes["onmouseover"] = "javascript:Highlight(this);";

Alternatively, try adding those attributes in the markup, IntelliSense won't tell you that they work, but they usually do (I haven't tested it specifically with MenuItems):

<asp:menuitem navigateurl="Home.aspx" 
    text="Home"
    imageurl="Images\Home.gif"
    popoutimageurl="Images\Popout.jpg"   
    tooltip="Home"
    style="color: red;" onmouseover="Highlight(this);" onmouseout="Unhighlight(this);"/>

You might have some luck with CSS Friendly Adapters.

Of course you can create an inherited class and re-work the rendering routines...

Pawel Krakowiak
Adding it to the markup doesn't work, it results in a parser error
MasterMax1313
And MenuItem doesn't have an Attributes member.
MasterMax1313
+3  A: 

Short of overriding RenderContents on Menu, your options are very limited. Most of what you'd need is private and sealed and you won't get anywhere there.

My solution would be to use templates. You could use MenuItem.Value or Depth and and ItemIndex to identify each item and provide necessary attributes.

In Page:

<asp:Menu ID="menu" runat="server" DynamicHorizontalOffset="2" StaticSubMenuIndent="10px">
 <Items>
  <asp:MenuItem Text="Item 1" Value="value 1">
   <asp:MenuItem Text="Item 2" Value="value 2">
    <asp:MenuItem Text="Item 3" Value="value 3"></asp:MenuItem>
   </asp:MenuItem>
   <asp:MenuItem Text="Item 4" Value="value 4">
    <asp:MenuItem Text="Item 5" Value="value 5"></asp:MenuItem>
   </asp:MenuItem>
   <asp:MenuItem Text="Item 6" Value="value 6"></asp:MenuItem>
  </asp:MenuItem>
  <asp:MenuItem Text="Item 7" Value="value 7"></asp:MenuItem>
  <asp:MenuItem Text="Item 8" Value="value 8"></asp:MenuItem>
 </Items>
 <StaticItemTemplate>
  <asp:Panel runat="server" ForeColor='<%# GetItemColor(Container) %>'>
   <%# Eval("Text") %> - <%# Eval("Value") %>
  </asp:Panel>
 </StaticItemTemplate>
 <DynamicItemTemplate>
  <asp:Panel ID="Panel1" runat="server" ForeColor='<%# GetItemColor(Container) %>'>
   <%# Eval("Text") %> - <%# Eval("Value") %>
  </asp:Panel>
 </DynamicItemTemplate>
</asp:Menu>

In Code (never mind silliness of this code, it is just to demonstrate the principle):

public Color GetItemColor(MenuItemTemplateContainer container)
{
 MenuItem item = (MenuItem)container.DataItem;

 //identify based value
 if (item.Value == "value 2")
  return Color.Brown;

 //identify based on depth and index
 if (item.Depth == 0)
  switch (container.ItemIndex)
  {
   case 0: return Color.Red;
   case 1: return Color.Blue;
   case 2: return Color.DarkGreen;
   default:
    return Color.Black;
  }
 else
  switch (container.ItemIndex)
  {
   case 0: return Color.Purple;
   case 1: return Color.Aqua;
   case 2: return Color.DarkOrange;
   default:
    return Color.Black;
  }
}
Ruslan
this is working perfectly for what I'm shooting for.
MasterMax1313
A: 

When I use aswer 1 above, exactly as shown I get "CS0246: The type or namespace name 'Color' could not be found (are you missing a using directive or an assembly reference?)"

What am I missing?

Thanks

Ok, I did figure out where to place the namespace code placed by Deviant. Now I get the following error: (menu code is below). Pls. Help.

CS0161: 'ASP.menutester_4_20_09_upper_spec_test_try1_aspx.GetItemColor(System.Web.UI.WebControls.MenuItemTemplateContainer)': not all code paths return a value

       <DynamicHoverStyle ForeColor="White" CssClass="hoverstyle3" BackColor="Black" BorderStyle="None" BorderWidth="0px" />

       <DynamicMenuStyle   BackColor="Black" Height="36px" />

       <DynamicMenuItemStyle BackColor="#0026FF"  Height="36px" BorderStyle="None" Width="200px" BorderWidth="0px" Font-Size="Medium" ForeColor="Black" />
       <DataBindings>
        <asp:menuitembinding DataMember="Menu" NavigateUrlField="url" TextField="text" />
        <asp:menuitembinding DataMember="SubMenu" NavigateUrlField="url" TextField="Text" />
       </DataBindings>
        <StaticHoverStyle ForeColor="White" BorderStyle="None" CssClass="hoverstyle" BorderWidth="0px" />

       <StaticMenuStyle BackColor="Black" Width="200px" BorderStyle="None" /> 

       <Items>
        <asp:menuitem Text="Latino Landscape" Value="Page 2">


        <asp:menuitem  Enabled="False" ImageUrl="Images/next.gif" Value="value 1" >
        </asp:menuitem> 
        <asp:menuitem Text="Top Profiles" Value="Top Profiles" NavigateUrl="http://www.hotmail.com" >
        </asp:menuitem>

        </asp:menuitem>


       </Items>
       <DynamicItemTemplate>
        <asp:Panel ID="Panel1" runat="server" ForeColor='<%# GetItemColor(Container) %>'> 
         <%# Eval("Text") %> - <%# Eval("Value") %>    

        </asp:Panel>        

       </DynamicItemTemplate>


      </asp:Menu>
<%@ Import Namespace="System.Drawing" %>
Chad Grant
New to this -- where does this go?I put it in the DynamicItemTemplate as follows and get an error. Thanks.<DynamicItemTemplate> <asp:Panel ID="Panel1" runat="server" ForeColor='<%# GetItemColor(Container) %>'> <%# Eval("Text") %> - <%# Eval("Value") %> <%@ Import Namespace="System.Drawing" %> </asp:Panel> </DynamicItemTemplate>
Ok, I did figure out where to place the namespace code placed by Deviant. Now I get the following error: Pls. Help.CS0161: 'ASP.menutester_4_20_09_upper_spec_test_try1_aspx.GetItemColor(System.Web.UI.WebControls.MenuItemTemplateContainer)': not all code paths return a value
I did get it going thanks.
OK, I have a new request: I would like to do something similar to the code in this thread, but instead of changing the background color for menu items, I would like to change the width. Specifically, I would like the first dynamic item to have a width of 3 px and all other dynamic items a width of 200 px.Thanks.
This has changed a bit. I actually want the first sub menu item to be 30 px wide, transparent, and w/a small picture in the middle. All lower submenu items will be 200px. I have this on a new post with a graphic link. Thanks http://stackoverflow.com/questions/865683/change-width-of-each-asp-menu-item