• 超级简单:一个横向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:

    代码
    <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
    ="M<u>e</u>nu2" 
                         description
    ="Menu2" accesskey="E" />
        
        
    <siteMapNode url="~/Views/Menu3.aspx" 
                     title
    ="Me<u>n</u>u3" 
                     description
    ="Menu3" 
                     accesskey
    ="N" target="_blank" />
            
        
    <siteMapNode url="~/Views/Menu4.aspx" 
                     title
    ="Men<u>u</u>4" 
                     description
    ="Menu4" accesskey="U">
          
    <siteMapNode url="~/Views/Menu4Sub1.aspx" 
                       title
    ="Menu4<u>S</u>ub1" 
                       description
    ="Menu4Sub1" 
                       accesskey
    ="S" />
          
    <siteMapNode url="~/Views/Menu4Sub2.aspx" 
                       title
    ="Menu4Su<u>b</u>2" 
                       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:

    代码
    <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来寻找accesskeytarget属性。每一个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:

    代码
    SiteMapNode SiteMap_SiteMapResolve(object sender, SiteMapResolveEventArgs e)
    {
        SiteMapNode currentNode 
    = SiteMap.CurrentNode.Clone(true);
        SiteMapNode tempNode 
    = currentNode;
        tempNode 
    = ReplaceNodeText(tempNode);

        
    return currentNode;
    }

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

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

        

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

    protected void Page_Load(object sender, EventArgs e)
    {
        
    if (Request.Browser.IsMobileDevice)
        {
            NavigationMenu.Visible 
    = false;
            NavigationTreeView.Visible 
    = true;
        }
    }

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

    代码
    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

    原文:http://www.codeproject.com/KB/webforms/Horizontal-Menu-Control.aspx



    (全文完)


    以下为广告部分

    您部署的HTTPS网站安全吗?

    如果您想看下您的网站HTTPS部署的是否安全,花1分钟时间来 myssl.com 检测以下吧。让您的HTTPS网站变得更安全!

    SSL检测评估

    快速了解HTTPS网站安全情况。

    安全评级(A+、A、A-...)、行业合规检测、证书信息查看、证书链信息以及补完、服务器套件信息、证书兼容性检测等。

    SSL证书工具

    安装部署SSL证书变得更方便。

    SSL证书内容查看、SSL证书格式转换、CSR在线生成、SSL私钥加解密、CAA检测等。

    SSL漏洞检测

    让服务器远离SSL证书漏洞侵扰

    TLS ROBOT漏洞检测、心血漏洞检测、FREAK Attack漏洞检测、SSL Poodle漏洞检测、CCS注入漏洞检测。

  • 相关阅读:
    重大技术需求系统八
    2020年下半年软考真题及答案解析
    周总结五
    重大技术需求系统七
    TextWatcher 编辑框监听器
    Android四大基本组件介绍与生命周期
    JAVA String,StringBuffer与StringBuilder的区别??
    iOS开发:保持程序在后台长时间运行
    宏定义的布局约束
    随便说一些
  • 原文地址:https://www.cnblogs.com/zhuqil/p/1629492.html
Copyright © 2020-2023  润新知