One question I see very frequently is how to customize the styles on an individual menu item. Declaratively, this isn't possible, although it is on the list of features for a future release. However, that doesn't mean it can't be done at all. It does take a little more work. So, here are a couple variations on a theme to help customize various items. The ideas here can be extended on easily and I expect we might see some pretty interesting Menu's out there in the future.
Here's the most straight forward brute force way of setting an individual item style:
<script runat="server">
Shared colorWheel As System.Collections.Generic.List(Of System.Drawing.Color)
Shared currentColor As System.Collections.Generic.List(Of System.Drawing.Color).Enumerator
Public Function GetBackColor() As System.Drawing.Color
If colorWheel Is Nothing Then
populatecolors()
End If
currentColor.MoveNext()
Return currentColor.Current
End Function
Private Sub populatecolors()
colorWheel = New System.Collections.Generic.List(Of System.Drawing.Color)
colorWheel.Add(Drawing.Color.Purple)
colorWheel.Add(Drawing.Color.Green)
colorWheel.Add(Drawing.Color.Brown)
colorWheel.Add(Drawing.Color.Chartreuse)
currentColor = colorWheel.GetEnumerator()
End Sub
</script>
<asp:Menu ID="Menu1" runat="server" Orientation="Horizontal"> <Items> <asp:MenuItem Text="one" Value="one"></asp:MenuItem> <asp:MenuItem Text="two" Value="two"></asp:MenuItem> <asp:MenuItem Text="three" Value="three"></asp:MenuItem> <asp:MenuItem Text="four" Value="four"></asp:MenuItem> </Items> <StaticItemTemplate> <asp:Label runat="server" ID="Label1" Text='<%# Eval("Text") %>' BackColor='<%# GetBackColor() %>' />
</StaticItemTemplate></asp:Menu>
Now, this isn't the most ideal code for a number of reasons, but it gets the job done. So lets make 2 improvements. First, lets use the Style property so that we're not limited to a single style. Second, lets get away from relying on matching the order in our style list and the order of declared items.
<script runat="server">
Shared styles As System.Collections.Generic.Dictionary(Of String, String)
Public Function GetStyle(ByVal value As String) As String
If styles Is Nothing Then
populateStyles()
End If
Return styles(value)
End Function
Private Sub populateStyles()
styles = New System.Collections.Generic.Dictionary(Of String, String)
styles("one") = "background-color:Blue; color:White;"
styles("two") = "background-color:Black; color:Yellow;"
styles("three") = "background-color:Purple; color:Black;"
styles("four") = "background-color:Green; color:Red;"
End Sub
</script>
<asp:Menu ID="Menu1" runat="server" Orientation="Horizontal"> <Items> <asp:MenuItem Text="one" Value="one"></asp:MenuItem> <asp:MenuItem Text="two" Value="two"> <asp:MenuItem Text="three" Value="three"></asp:MenuItem> <asp:MenuItem Text="four" Value="four"></asp:MenuItem> </asp:MenuItem>
</Items> <StaticItemTemplate> <asp:Label runat="server" ID="Label1" Text='<%# Eval("Text") %>' Style='<%# GetStyle( Eval("Value") ) %>' /> </StaticItemTemplate> <DynamicItemTemplate>
<asp:Label runat="server" ID="Label1" Text='<%# Eval("Text") %>' Style='<%# GetStyle( Eval("Value") ) %>' /> </DynamicItemTemplate></
asp:Menu>
With this improvement, we have a lot control. Dynamic items also aren't a problem (although technically they weren't with the first method). With a bit of a variation, we can also make this work with a databound Menu like this:
<script runat="server">
Shared styles As New System.Collections.Generic.Dictionary(Of String, String)
Protected Sub Menu1_MenuItemDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.MenuEventArgs)
styles(e.Item.ValuePath) = CType(e.Item.DataItem, SiteMapNode)("style")
End Sub </script>
<asp:Menu ID="Menu1" runat="server" DataSourceID="SiteMapDataSource1"
OnMenuItemDataBound="Menu1_MenuItemDataBound">
<StaticItemTemplate>
<asp:Label runat="server" ID="Label1" Text='<%# Eval("Text") %>'
Style='<%# styles( Eval("ValuePath") ) %>' />
</StaticItemTemplate>
<DynamicItemTemplate>
<asp:Label runat="server" ID="Label1" Text='<%# Eval("Text") %>'
Style='<%# styles( Eval("ValuePath") ) %>' />
</DynamicItemTemplate>
</asp:Menu>
[web.sitemap]
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="root.aspx" title="root" style="">
<siteMapNode url="one.aspx" title="one" style="background-color:Blue; color:White;" />
<siteMapNode url="two.aspx" title="two" style="background-color:Black; color:Yellow;">
<siteMapNode url="three.aspx" title="three" style="background-color:Purple; color:Black;" />
<siteMapNode url="four.aspx" title="four" style="background-color:Green; color:Red;" />
</siteMapNode>
</siteMapNode>
</siteMap>