超级简单:一个ASP.NET横向Menu控件

   几个星期前,开始了一个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包含一个accesskeytarget属性值。

Listing 1:

ExpandedBlockStart.gif 代码
<!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --&gt < siteMapNode >
      
< siteMapNode  url ="Default.aspx"  
         title
="& lt;u>H& lt;/u>ome"  
         description
="Home"  
         accesskey
="H"   />
      
< siteMapNode  url ="~/Views/Menu1.aspx"  
                   title
="& lt;u>M& lt;/u>enu1"   
                   description
="Menu1"  accesskey ="M"   />
        
< siteMapNode  url ="~/Views/Menu2.aspx"  
                     title
="Menu2"  
                     description
="Menu2"  accesskey ="E"   />
    
    
< siteMapNode  url ="~/Views/Menu3.aspx"  
                 title
="Menu3"  
                 description
="Menu3"  
                 accesskey
="N"  target ="_blank"   />
        
    
< siteMapNode  url ="~/Views/Menu4.aspx"  
                 title
="Menu4"  
                 description
="Menu4"  accesskey ="U" >
      
< siteMapNode  url ="~/Views/Menu4Sub1.aspx"  
                   title
="Menu4Sub1"  
                   description
="Menu4Sub1"  
                   accesskey
="S"   />
      
< siteMapNode  url ="~/Views/Menu4Sub2.aspx"  
                   title
="Menu4Sub2"  
                   description
="Menu4Sub2"  
                   target
="_blank"  accesskey ="B"   />
    
siteMapNode >
……
….
  
siteMapNode >
siteMap >

       添加一个Master Pag到我们的website项目中,拖一个SiteMapDataSource控件到页面上,接着拖一个Menu控件,Menu控件包含在一个div里面,menu每个属性都能在这里被找到,

设置 staticdisplaylevels ="2"orientation="Horizontal"来横向的显示menu控件。我们可以使用内联样式表或放置在一个外部文件中的CSS样式。在本例中,CSS样式位于style.css文件。

Listing 2:

ExpandedBlockStart.gif 代码
<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--&gt < 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:

ExpandedBlockStart.gif 代码
<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--&gt < 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呈现或者显示之前,为菜单项创造一个访问键。后者是修改的SiteMapPath控件显示的文本。

 

<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--&gt NavigationMenu.MenuItemDataBound  +=  
     
new  MenuEventHandler(NavigationMenu_MenuItemDataBound);
SiteMap.SiteMapResolve 
+=  
     
new  SiteMapResolveEventHandler(SiteMap_SiteMapResolve);

 

   下面显示的是该NavigationMenu_MenuItemDataBound实现的方法。在Menu控件中的菜单项绑定数据时,MenuItemDataBound事件发生。话虽如此,这将通过循环SiteMapNode来寻找accesskey和target属性。有一个target属性与菜单项关联,我们可以用target属性值来设置目标窗口。

 

ExpandedBlockStart.gif 代码
<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--&gt 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);
    }
}

    要获得访问键,将在母版页上添加一个Panel控件和一个JavaScript函数重定向到指定的一个网页。请看Listing 6

 Listing 6:

<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--&gt < asp:Panel ID = " AccessKeyPanel "  runat = " server "   />
< script type = " text/javascript " >
 function navigateTo(url) {
    window.location 
=  url;
 }
script >

  下面是CreateAccessKeyButton方法的实现。动态的创建一个HtmlButton控件,给它添加一个onclick事件。设置style.left样式属性为-255px来隐藏这个控件。

ExpandedBlockStart.gif 代码
<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--&gt // 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:

ExpandedBlockStart.gif 代码
<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--&gt SiteMapNode SiteMap_SiteMapResolve( object  sender, SiteMapResolveEventArgs e)
{
    SiteMapNode currentNode 
=  SiteMap.CurrentNode.Clone( true );
    SiteMapNode tempNode 
=  currentNode;
    tempNode 
=  ReplaceNodeText(tempNode);

    
return  currentNode;
}

// remove  tag recursively
internal  SiteMapNode ReplaceNodeText(SiteMapNode smn)
{
    
// current node
     if  (smn  !=   null   &&  smn.Title.Contains( " " ))
    {
        smn.Title 
=  smn.Title.Replace( " "
                       
"" ).Replace( " " "" );
    }

    
// parent node
     if  (smn.ParentNode  !=   null )
    {
        
if  (smn.ParentNode.Title.Contains( " " ))
        {
            SiteMapNode gpn 
=  smn.ParentNode;
            smn.ParentNode.Title 
=  smn.ParentNode.Title.Replace(
              
" " "" ).Replace( " " "" );
            smn 
=  ReplaceNodeText(gpn);
        }
    }
    
return  smn;
}

     由于菜单是在母版页中,右击website project,添加新项,Web Form,勾选选择母板页checkbox。

     在移动设备上,悬停菜单似乎无法显示。为了解决这个问题,我使用一个TreeView控件并设置其Visible属性为false。默认情况下,这个控件展开它所有的节点的,这将需要对上述问题进行处理。如果请求浏览是一个移动设备,在后台代码中,隐藏的菜单控件和显示TreeView控件。

<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--&gt protected   void  Page_Load( object  sender, EventArgs e)
{
    
if  (Request.Browser.IsMobileDevice)
    {
        NavigationMenu.Visible 
=   false ;
        NavigationTreeView.Visible 
=   true ;
    }
}

     当我在IE 8中测试菜单时,悬停菜单也没有正确呈现。为了克服这个问题, 我们设置DynamicMenuStyle. z-index 为200。子菜单在谷歌浏览器不能运行。经过一番研究,我找到了解决的办法。见下面。

ExpandedBlockStart.gif 代码
<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--&gt protected   void  Page_Load( object  sender, EventArgs e)
{
    
if  (Request.UserAgent.IndexOf( " AppleWebKit " >   0 )
    {
        Request.Browser.Adapters.Clear();
        NavigationMenu.DynamicMenuStyle.Width 
=  Unit.Pixel( 120 );
    }
}

     如果您发现任何错误或对内容有不同的意见,请给我留言,我会与你一起加以纠正。

效果:http://download.ysatech.com/ASP-NET-Menu-Control/

代码:/Files/zhuqil/MenuControl.zip

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12639172/viewspace-623288/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12639172/viewspace-623288/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值