如何使用CSS样式化ASP.NET菜单

24

我正在为一个asp.net菜单设置样式,我试图理解StaticSelectedStyle-CssClass和StaticHoverStyle-CssClass参数的含义。

据我了解,使用这些参数定义的样式会在需要时作为CSS类应用于相关元素。因此,我按照以下方式创建了我的菜单:

<asp:Menu ID="NavigationMenu" DataSourceID="NavigationSiteMapDataSource" 
        StaticMenuStyle-CssClass="StaticMenuStyle"
        StaticMenuItemStyle-CssClass="StaticMenuItemStyle"
        StaticSelectedStyle-CssClass="StaticSelectedStyle"
        StaticHoverStyle-CssClass="StaticHoverStyle"
        Orientation="Horizontal" 
        MaximumDynamicDisplayLevels="0" 
        runat="server">
</asp:Menu>

对于StaticMenuStyle-CssClass和StaticMenuStyle-CssClass它是有效的(这些类应用于相关元素),但是不管元素选择或悬停状态如何,StaticSelectedStyle-CssClass和StaticHoverStyle-CssClass都不会被应用。

我应该做什么才能使它起作用?

谢谢。

编辑:抱歉我应该提到这是.NET 4。以下是生成的HTML代码:

<div id="NavigationMenu">
 <ul class="level1 StaticMenuStyle">
  <li><a class="level1 StaticMenuItemStyle selected" href="/Link.aspx">Link</a></li>
 </ul>
</div>

正如你所看到的,应用了StaticMenuStyle和StaticMenuItemStyle,但没有应用StaticSelectedStyle-CssClass或StaticHoverStyle-CssClass。不确定为什么。我知道我可以使用selected,但是预期的行为难道不是应用StaticSelectedStyle-CssClass吗?通过使用selected,我会对.NET在幕后做出哪些假设,这是不正确的。


对我来说它运行良好(使用更简单的示例 - 例如,我的菜单没有数据绑定)。您能否发布相关的CSS类以及一些呈现的HTML? - Jeff Sternal
在标记中查找一些设置悬停样式的Javascript代码。在使用表格的原始布局中,只有在单击菜单选项之一并且菜单执行回发后才会应用所选样式。 - Harv
4
不行,没有帮助。无论如何我的课程都没有被设置。看起来像是一个错误。 - md1337
11个回答

35

我感同身受,我浪费了一个晚上/早上的时间来尝试解决这个问题。 通过纯粹的强制手段,我找到了一个解决方案。称其为变通方法 - 但它很简单。

像这样将CssClass属性添加到您的菜单控件声明中:

<asp:Menu ID="NavigationMenu" DataSourceID="NavigationSiteMapDataSource"
        CssClass="SomeMenuClass"
        StaticMenuStyle-CssClass="StaticMenuStyle"
        StaticMenuItemStyle-CssClass="StaticMenuItemStyle"
        Orientation="Horizontal" 
        MaximumDynamicDisplayLevels="0" 
        runat="server">
</asp:Menu>

只需删除StaticSelectedStyle-CssClass和StaticHoverStyle-CssClass属性,因为它们根本不起作用。

现在创建“SomeMenuClass”,无论您放入什么都无所谓。 它应该长这样:

.SomeMenuClass
{
    color:Green;
}

接下来,添加以下两个CSS类:

要添加“悬停”样式,请添加:

.SomeMenuClass a.static.highlighted
{
    color:Red !important;
}

要为“已选择”设置样式,请添加:

.SomeMenuClass a.static.selected
{
    color:Blue !important;
}

好的,这就是全部内容了。希望能够帮助到一些和我一样苦恼的人。顺便说一下,你提到:

我似乎是第一个报告这个似乎是bug的人。

你似乎也认为这是一个新的.NET 4.0 bug。我找到了这个链接: http://www.velocityreviews.com/forums/t649530-problem-with-staticselectedstyle-and-statichoverstyle.html 它是关于Asp.Net 2.0的,发布于2008年。我们怎么会是地球上唯一抱怨这个问题的三个人呢?

我是通过研究HTML输出找到了解决方法的:

下面是当我设置StaticHoverStyle-BackColor="Red"时的HTML输出:

#NavigationMenu a.static.highlighted
{
    background-color:Red;
}

当设置StaticSelectedStyle-BackColor="Blue"时,这是HTML输出:

#NavigationMenu a.static.selected
{
    background-color:Blue;
    text-decoration:none;
}
因此,覆盖这个标记的逻辑方法是为SomeMenuClass a.static.highlightedSomeMenuClass a.static.selected创建类。
特别注意:
您必须在这些类中的所有设置上使用“!important”,因为HTML输出使用“#NavigationMenu”,这意味着Asp.Net决定为您添加任何样式将具有菜单控件ID“NavigationMenu”的继承优先级。我遇到的一个问题是填充,直到我发现Asp.Net正在使用“#NavigationMenu”将左右填充设置为15em。我在我的SomeMenuClass样式中添加了“!important”,它就起作用了。

2
哎呀!我试过了,你说得对。我觉得没人用 ASP.Net 菜单,因为它太糟糕了。每个版本都在改进它,但他们似乎就是不明白最基本的要求。难道你不希望在菜单上标示选中项吗? - DOK
1
我认为大多数人都会放弃,然后从头开始构建他们自己的菜单。我坚持下来,最终能够让它工作,但我不得不研究生成的HTML,以找出如何编写CSS,并反复调整,直到在过去的3个版本中在所有浏览器中呈现相同。真是太痛苦了,但我能够避免使用JavaScript构建自定义交互式菜单。需要注意的一件事是ASP.net菜单的默认呈现模式在4.0中发生了变化。请参见此处的“备注”部分:http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.menu.renderingmode.aspx - MikeTeeVee
@MikeTeeVee 这真的为我节省了几个小时,谢谢。你知道如何在每个水平菜单链接之间添加分隔符图像吗? - Mark B

8

好的,截至今天,显然还没有很多人尝试使用.NET 4菜单。这并不奇怪,因为最终版本是在几天前发布的。我似乎是第一个报告似乎存在错误的人。如果有时间,我会向微软报告此问题,但考虑到微软不重视漏洞报告的记录,我不会急于处理它。

无论如何,在这一点上,最不错的解决方案是复制并粘贴由控件生成的CSS样式(检查标题)到您自己的样式表中,并从那里进行修改。完成后,请不要忘记在菜单上设置IncludeStyleBlock =“False”,以防止自动生成CSS,因为我们现在将使用复制的块。从概念上讲,这是不正确的,因为您的应用程序不应依赖于自动生成的代码,但这是我能想到的唯一选项。


我刚刚将我的选定类命名为“selected”,这对我来说很有效,感谢您的提示。 - MikeAinOz
你的解决方案对我来说似乎是最好的,因为我不需要覆盖实现特定类别(如'a.static')的样式。我确实失去了一些我需要的样式,但现在我能够仅基于菜单和项目的CssClass属性指定的类别进行样式设置。 - madannes

4

我记得StaticSelectedStyle-CssClass属性曾经在ASP.NET 2.0中起作用。在.NET 4.0中,如果更改菜单控件的RenderingMode属性为“Table”(因此使其像05年那样呈现菜单和子菜单),它至少会将您指定的StaticSelectedStyle-CssClass写入正确的HTML元素中。

这可能已经足够让您的页面按照您的要求工作。然而,在ASP 4.0中解决选定的菜单项(当将RenderingMode保留为默认值时)时,我的解决方法是模仿控件生成的“selected”CSS类别,但给我的样式加上“!important”CSS声明,以便在需要时我的样式优先。

例如,默认情况下,菜单控件呈现每个菜单项的“li”元素和子“a”元素,并且所选菜单项的“a”元素将包含class =“selected”(其中还包括“static”,如果它是一个静态菜单项),因此我将我的自己的选择器添加到页面中(或者在单独的样式表文件中),“static”和“selected”“a”标签如下:

a.selected.static
{
background-color: #f5f5f5 !important;
border-top: Red 1px solid !important;
border-left: Red 1px solid !important;
border-right: Red 1px solid !important;
} 

3
我遇到了一个问题,就是我的菜单项上没有添加“selected”类。结果发现,由于某种原因,不能在其上设置NavigateUrl。
我删除了NavigateUrl后,它就将“selected”CSS类应用于a标签,并且我能够使用以下方式设置背景样式:
div.menu ul li a.static.selected
{
    background-color: #bfcbd6 !important;
    color: #465c71 !important;
    text-decoration: none !important;
}

2

我只是想提供一些帮助,以帮助仍然遇到这个问题的人。(至少对我来说) CSS 显示它在每个菜单项上放置了默认的 level1、level2 和 level3 类(其中 level1 是菜单,level2 是第一个下拉菜单,level3 是第三个弹出菜单)。在 CSS 中设置填充

.level2
{
padding: 2px 2px 2px 2px;
}

这段代码可以为第一个下拉菜单中的每个li元素添加padding。


2

这对我有用 - 我的情况与 OP 稍有不同,因为我的菜单是静态定义的,而不是使用数据源。 - Gary Stacey

1

我不知道为什么这里所有的答案都那么令人困惑。我找到了一个相当简单的方法。在 asp:menu 上使用 css 类,比如说 mainMenu,在渲染成 HTML 后,所有的菜单项都将是 "a 标签"。所以你只需要在 CSS 中为这些 "a 标签" 提供 :hover 属性即可。 以下是示例:

<asp:Menu ID="mnuMain" Orientation="Horizontal" runat="server" Font-Bold="True" Width="100%" CssClass="mainMenu">
  <Items>
    <asp:MenuItem Text="Home"></asp:MenuItem>
    <asp:MenuItem Text="About Us"></asp:MenuItem>
  </Items>
</asp:Menu>

在CSS中编写以下内容:
.mainMenu { background:#900; }
.mainMenu a { color:#fff; }
.mainMenu a:hover { background:#c00; color:#ff9; }

我希望这有所帮助。 :)

1
要注意的是控件输出的HTML内容。在这种情况下,它会输出一个表格来创建菜单。悬停样式设置在TD上,一旦选择了菜单项,控件就会回传并将所选样式添加到TD内链接的A标签中。
因此,在这里有两个不同的元素被操作。一个是TD元素,另一个是A元素。因此,您必须相应地使您的CSS工作。如果我将以下CSS添加到带有菜单的页面中,那么无论哪种情况下都会得到预期的背景颜色更改行为。您可能正在进行一些不同的CSS操作,这些操作可能适用于这些元素,也可能不适用。
<style>
    .StaticHoverStyle
    {
        background: #000000;
    }

    .StaticSelectedStyle
    {
        background: blue;
    }
</style>

2
我感谢您的评论。我忘了提到这是.NET 4,因此默认呈现的是列表而不是表格。 - md1337
1
然后我会检查应用于列表的样式。我这里没有安装VS2010,所以无法给您直接的提示,但如果它的工作方式类似于原始设置,那么他们可能会直接应用某些样式到生成的标记或使用JavaScript,并且您需要检查这些样式以及它们被应用的位置。 - Harv
3
您是正确的,我注意到了这一点,但请看我的编辑,我认为这不是解决方案的原因。 - md1337

0

你可以尝试使用LevelSubMenuStyles进行样式设置

            <asp:Menu ID="mainMenu" runat="server" Orientation="Horizontal" 
                StaticEnableDefaultPopOutImage="False">
                <StaticMenuStyle CssClass="test" />
                <LevelSubMenuStyles>
                    <asp:SubMenuStyle BackColor="#33CCFF" BorderColor="#FF9999" 
                        Font-Underline="False" />
                    <asp:SubMenuStyle BackColor="#FF99FF" Font-Underline="False" />
                </LevelSubMenuStyles>
                <StaticMenuItemStyle CssClass="main-nav-item" />
            </asp:Menu>

0
我在处理这个有问题的控件时,最好的结果是完全不使用CSS,而是使用内置的控件属性来设置样式(如DynamicMenuItemStyle-BackColor、StaticHoverStyle-Width等)。这是一种可怕的做法,会使你的代码变得臃肿,并迫使你为每个控件实例都这样做。
然而,这确实有效。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接