几个星期前,开始了一个ASP.NET Web应用程序,需要一个简单的横向的带子菜单的Menu控件。将Menu控件拖拽到一个页面上时,我就决定使用ASP.NET的Menu控件。这个控件很简单,但该控件不提供访问的key和支持菜单窗体的target。我把这些功能放在一起将如何去实现:
1、包含accesskey属性
2、包含target
属性
3、包含Site Map Path
这是项目工程的结构,欢迎你下载这个Demo。
首先,添加一个Site Map 到我们的website工程。打开web.sitemap文件,添加你的导航数据和导航结构。为了强调一个菜单标题的某些特征,我们可以使用HTML下划线记 (<u></u>
)。为了正确地解析XML,我们必须用 & lt;取代小于号(<)。每个siteMapNode包含一个accesskey 和target属性值。
Listing 1:
添加一个Master Pag到我们的website项目中,拖一个SiteMapDataSource控件到页面上,接着拖一个Menu控件,Menu控件包含在一个div里面,menu每个属性都能在这里被找到,
设置 staticdisplaylevels ="2"
和orientation="Horizontal"来横向的显示menu控件。我们可以使用内联样式表或放置在一个外部文件中的CSS样式。在本例中,CSS样式位于style.css文件。
Listing 2:
代码
<
asp:SiteMapDataSource
id
="MenuSource"
runat
="server"
/>
<
div
class
="background"
>
<
asp:menu
id
="NavigationMenu"
CssClass
="NavigationMenu"
staticdisplaylevels
="2"
DynamicHorizontalOffset
="1"
staticsubmenuindent
="1px"
MaximumDynamicDisplayLevels
="4"
orientation
="Horizontal"
DynamicPopOutImageUrl
="~/Images/right-arrow.gif"
StaticPopOutImageUrl
="~/Images/drop-arrow.gif"
datasourceid
="MenuSource"
runat
="server"
Height
="30px"
>
<
staticmenuitemstyle
ItemSpacing
="10"
CssClass
="staticMenuItemStyle"
/>
<
statichoverstyle
CssClass
="staticHoverStyle"
/>
<
StaticSelectedStyle
CssClass
="staticMenuItemSelectedStyle"
/>
<
DynamicMenuItemStyle
CssClass
="dynamicMenuItemStyle"
/>
<
dynamichoverstyle
CssClass
="menuItemMouseOver"
/>
<
DynamicMenuStyle
CssClass
="menuItem"
/>
<
DynamicSelectedStyle
CssClass
="menuItemSelected"
/>
<
DataBindings
>
<
asp:MenuItemBinding
DataMember
="siteMapNode"
NavigateUrlField
="url"
TextField
="title"
ToolTipField
="description"
/>
</
DataBindings
>
</
asp:menu
>
</
div
>
拖一个SiteMapPath 控件到页面上。这个控件的目的是显示导航路径和显示用户当前页的位置。请看看Listing 3。
Listing 3:
代码
<
div
id
="e"
>
<
asp:SiteMapPath
ID
="SiteMapPath1"
runat
="server"
RenderCurrentNodeAsLink
="true"
CssClass
="currentNodeStyle"
PathSeparator
=" >> "
>
<
PathSeparatorStyle
ForeColor
="#5D7B9D"
CssClass
="currentNodeStyle"
/>
<
CurrentNodeStyle
ForeColor
="#333333"
CssClass
="currentNodeStyle"
/>
<
NodeStyle
ForeColor
="#7C6F57"
CssClass
="currentNodeStyle"
/>
<
RootNodeStyle
ForeColor
="#5D7B9D"
CssClass
="currentNodeStyle"
/>
</
asp:SiteMapPath
>
</
div
>
在Page_Load事件中包括MenuItemDataBound和SiteMapResolve事件处理程序。前者的目的是插入target的属性值,在Meun呈现或者显示之前,为菜单项创造accesskey。后者是修改的SiteMapPath控件显示的文本。
NavigationMenu.MenuItemDataBound
+=
new
MenuEventHandler(NavigationMenu_MenuItemDataBound);
SiteMap.SiteMapResolve
+=
new
SiteMapResolveEventHandler(SiteMap_SiteMapResolve);
下面显示的是该NavigationMenu_MenuItemDataBound实现的方法。在Menu控件中的菜单项绑定数据时,触发MenuItemDataBound事件发生。话虽如此,这将通过循环SiteMapNode来寻找accesskey
和target
属性。每一个target属性与菜单项关联,我们可以用target属性值来设置目标窗口。
代码
void
NavigationMenu_MenuItemDataBound(
object
sender, MenuEventArgs e)
{
SiteMapNode node
=
(SiteMapNode)e.Item.DataItem;
//
set the target of the navigation menu item (blank, self, etc...)
if
(node[
"
target
"
]
!=
null
)
{
e.Item.Target
=
node[
"
target
"
];
}
//
create access key button
if
(node[
"
accesskey
"
]
!=
null
)
{
CreateAccessKeyButton(node[
"
accesskey
"
]
as
string
, node.Url);
}
}
要获得accesskey,将在母版页上添加一个Panel控件和一个重定向到指定的一个网页的JavaScript函数。请看Listing 6
Listing 6:
<
asp:Panel ID
=
"
AccessKeyPanel
"
runat
=
"
server
"
/>
<
script type
=
"
text/javascript
"
>
function navigateTo(url) {
window.location
=
url;
}
</
script
>
下面是CreateAccessKeyButton方法的实现。动态的创建一个HtmlButton控件,给它添加一个onclick事件。设置style.left样式属性为-255px来隐藏这个控件。
代码
//
create access key button
void
CreateAccessKeyButton(
string
ak,
string
url)
{
HtmlButton inputBtn
=
new
HtmlButton();
inputBtn.Style.Add(
"
width
"
,
"
1px
"
);
inputBtn.Style.Add(
"
height
"
,
"
1px
"
);
inputBtn.Style.Add(
"
position
"
,
"
absolute
"
);
inputBtn.Style.Add(
"
left
"
,
"
-2555px
"
);
inputBtn.Style.Add(
"
z-index
"
,
"
-1
"
);
inputBtn.Attributes.Add(
"
type
"
,
"
button
"
);
inputBtn.Attributes.Add(
"
value
"
,
""
);
inputBtn.Attributes.Add(
"
accesskey
"
, ak);
inputBtn.Attributes.Add(
"
onclick
"
,
"
navigateTo('
"
+
url
+
"
');
"
);
AccessKeyPanel.Controls.Add(inputBtn);
}
当CurrentNode属性被访问时,SiteMap.SiteMapResolve事件被触发。这将调用递归的ReplaceNodeText方法,来替换HTML下划线标记
。请看Listing 8
Listing 8:
在移动设备上,悬停菜单似乎无法显示。为了解决这个问题,我使用一个TreeView控件并设置其Visible属性为false。默认情况下,这个控件展开它所有的节点的。这将需要对上述问题进行处理。如果请求浏览是一个移动设备,在后台代码中,隐藏的菜单控件和显示TreeView控件。
当我在IE 8中测试菜单时,悬停菜单也没有正确呈现。为了克服这个问题, 我们设置DynamicMenuStyle z-index 为200。子菜单在谷歌浏览器不能运行。经过一番研究,我找到了解决的办法。见下面。
如果您发现任何错误或对内容有不同的意见,请给我留言,我会与你一起加以纠正。
效果:http://download.ysatech.com/ASP-NET-Menu-Control/
代码:/Files/zhuqil/MenuControl.zip
原文:http://www.codeproject.com/KB/webforms/Horizontal-Menu-Control.aspx