如何实现在Asp.net下XP风格的下拉菜单

结合Jst和Css实现了在Asp.net下XP风格的下拉菜单,效果图如下:





实现的步骤及源码如下:
Default.aspx代码:

 1<%@ Page language="c#" Codebehind="default.aspx.cs" AutoEventWireup="false" Inherits="PopupMenuControlSample._default" %>
 2<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
 3<HTML>
 4    <HEAD>
 5        <title>PopupMenu control sample</title>
 6        <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
 7        <meta content="C#" name="CODE_LANGUAGE">
 8        <meta content="JavaScript" name="vs_defaultClientScript">
 9        <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
10        <LINK href="PopupMenuSample.css" type="text/css" rel="Stylesheet">
11    </HEAD>
12    <body bgColor="#ffffcc" MS_POSITIONING="GridLayout">
13        <form id="MainForm" method="post" runat="server">
14            <asp:label id="PopupMenuOwner" Runat="server" CssClass="MainText">Click on me to show the popup menu</asp:label>
15        </form>
16    </body>
17</HTML>
18



Default.aspx.cs代码:

  1using System;
  2using System.Collections;
  3using System.ComponentModel;
  4using System.Data;
  5using System.Drawing;
  6using System.Web;
  7using System.Web.SessionState;
  8using System.Web.UI;
  9using System.Web.UI.WebControls;
 10using System.Web.UI.HtmlControls;
 11using UIControl;
 12
 13namespace PopupMenuControlSample
 14{
 15    /// <summary>
 16    /// Summary description for _default.
 17    /// </summary>

 18    public class _default : System.Web.UI.Page
 19    {
 20        const string ControlContainer = "MainForm";
 21        const string ClickedMessage = "<BR/><BR/>The menu item '{0}' has been selected by the user.";
 22        const string NoMenuItemClicked = "<BR/><BR/>No menu item has been clicked yet.";
 23        const string MessageStyle = "Message";
 24        const string MenuControlID = "PopupMenu";
 25        const MenuItemDirection MenuDirection = MenuItemDirection.Vertical;
 26        const string PopupMenuParentID = "PopupMenuOwner";
 27        const string Services = "Services";
 28        const string ServicesAltText = "available services";
 29        const string ServicesName = "Services";
 30        const string ServicesJavaScript = null;
 31        const string ServicesImageUrl = null;
 32        const MenuItemDirection ServicesDirection = MenuItemDirection.Vertical;
 33        const string ServicesTableID = "Services";
 34        const string AboutMe = "About me";
 35        const string AboutMeAltText = "about me";
 36        const string AboutMeName = "AboutMe";
 37        const string AboutMeJavaScript = null;
 38        const string AboutMeImageUrl = null;
 39        const MenuItemDirection AboutMeDirection = MenuItemDirection.Vertical;
 40        const string AboutMeTableID = "AboutMe";
 41        const string UsefulLinks = "Useful links";
 42        const string UsefulLinksAltText = "useful links";
 43        const string UsefulLinksName = "UsefulLinks";
 44        const string UsefulLinksJavaScript = null;
 45        const string UsefulLinksImageUrl = null;
 46        const MenuItemDirection UsefulLinksDirection = MenuItemDirection.Vertical;
 47        const string UsefulLinksTableID = "UsefulLinks";
 48        const string Presenter = ".NET Presenter";
 49        const string PresenterAltText = "presenter for your .NET usergroup or show";
 50        const string PresenterName = "Presenter";
 51        const string PresenterJavaScript = null;
 52        const string PresenterImageUrl = "images/presenter.gif";
 53        const string PresenterTableID = "Presenter";
 54        const string Author = ".NET author";
 55        const string AuthorAltText = "author for your .NET magazine";
 56        const string AuthorName = "Author";
 57        const string AuthorJavaScript = "window.alert('Klaus Salchner, Chief Enterprise Architect');";
 58        const string AuthorImageUrl = null;
 59        const string AuthorTableID = "Author";
 60        const string Architect = ".NET architecture review";
 61        const string ArchitectAltText = "architecture review for your .NET project";
 62        const string ArchitectName = "Architect";
 63        const string ArchitectJavaScript = null;
 64        const string ArchitectImageUrl = "images/review.gif";
 65        const string ArchitectTableID = "Architect";
 66        const string Resume = "Resume";
 67        const string ResumeAltText = "my resume";
 68        const string ResumeName = "Resume";
 69        const string ResumeJavaScript = null;
 70        const string ResumeImageUrl = null;
 71        const string ResumeTableID = "Resume";
 72        const string ContactMe = "Contact me";
 73        const string ContactMeAltText = "contact me";
 74        const string ContactMeName = "ContactMe";
 75        const string ContactMeJavaScript = null;
 76        const string ContactMeImageUrl = "images/contactme.gif";
 77        const string ContactMeTableID = "ContactMe";
 78        const string CodeGuru = "CodeGuru";
 79        const string CodeGuruAltText = "CodeGuru";
 80        const string CodeGuruName = "CodeGuru";
 81        const string CodeGuruJavaScript = null;
 82        const string CodeGuruImageUrl = "images/codeguru.gif";
 83        const string CodeGuruTableID = "CodeGuru";
 84        const string DeveloperLand = "DeveloperLand";
 85        const string DeveloperLandAltText = "DeveloperLand";
 86        const string DeveloperLandName = "DeveloperLand";
 87        const string DeveloperLandJavaScript = null;
 88        const string DeveloperLandImageUrl = "images/developerland.gif";
 89        const string DeveloperLandTableID = "DeveloperLand";
 90        const string Msdn = "MSDN";
 91        const string MsdnAltText = "MSDN";
 92        const string MsdnName = "Msdn";
 93        const string MsdnJavaScript = null;
 94        const string MsdnImageUrl = "images/msdn.gif";
 95        const string MsdnTableID = "Msdn";
 96        const string GotDotNet = "Got-Dot-Net";
 97        const string GotDotNetAltText = "Got-Dot-Net";
 98        const string GotDotNetName = "GotDotNet";
 99        const string GotDotNetJavaScript = null;
100        const string GotDotNetImageUrl = null;
101        const string GotDotNetTableID = "GotDotNet";
102        private Label Message;
103        protected System.Web.UI.WebControls.Label PopupMenuOwner;
104
105        Web Form Designer generated code
125
126        /// <summary>
127        /// initialize the form; allows us to add new controls to it
128        /// </summary>
129        /// <param name="sender">event sender</param>
130        /// <param name="e">event argument</param>

131        private void Page_Init(object sender, System.EventArgs e)
132        {
133            // create a new popup menu control to display
134            PopupMenuControl MyPopupMenu = new PopupMenuControl();
135            MyPopupMenu.MenuDirection = MenuDirection;
136            MyPopupMenu.MenuShowSubMenuIndicator = true;
137            MyPopupMenu.PopupMenuParentID = PopupMenuParentID;
138            MyPopupMenu.ShowVerticalMenuImageBar = true;
139            MyPopupMenu.ID = MenuControlID;
140
141            // create the popup-menu items
142            MyPopupMenu.PopupMenu.Add(new PopupMenuItemDetails(Services, ServicesAltText, ServicesName, ServicesJavaScript, ServicesImageUrl, null, ServicesDirection, ServicesTableID, true));
143            MyPopupMenu.PopupMenu.Add(new PopupMenuItemDetails(AboutMe, AboutMeAltText, AboutMeName, AboutMeJavaScript, AboutMeImageUrl, null, AboutMeDirection, AboutMeTableID, true));
144            MyPopupMenu.PopupMenu.Add(new PopupMenuItemDetails(UsefulLinks, UsefulLinksAltText, UsefulLinksName, UsefulLinksJavaScript, UsefulLinksImageUrl, null, UsefulLinksDirection, UsefulLinksTableID, true));
145
146            // create the services sub-menu
147            MyPopupMenu.PopupMenu[0].PopupSubMenus = new PopupMenuItemDetailsCollection();
148            MyPopupMenu.PopupMenu[0].PopupSubMenus.Add(new PopupMenuItemDetails(Presenter, PresenterAltText, PresenterName, PresenterJavaScript, PresenterImageUrl, null, MenuItemDirection.Vertical, PresenterTableID, false));
149            MyPopupMenu.PopupMenu[0].PopupSubMenus.Add(new PopupMenuItemDetails(Author, AuthorAltText, AuthorName, AuthorJavaScript, AuthorImageUrl, null, MenuItemDirection.Vertical, AuthorTableID, false));
150            MyPopupMenu.PopupMenu[0].PopupSubMenus.Add(new PopupMenuItemDetails(Architect, ArchitectAltText, ArchitectName, ArchitectJavaScript, ArchitectImageUrl, null, MenuItemDirection.Vertical, ArchitectTableID, false));
151
152            // create the about-me sub-menu
153            MyPopupMenu.PopupMenu[1].PopupSubMenus = new PopupMenuItemDetailsCollection();
154            MyPopupMenu.PopupMenu[1].PopupSubMenus.Add(new PopupMenuItemDetails(Resume, ResumeAltText, ResumeName, ResumeJavaScript, ResumeImageUrl, null, MenuItemDirection.Vertical, ResumeTableID, false));
155            MyPopupMenu.PopupMenu[1].PopupSubMenus.Add(new PopupMenuItemDetails(ContactMe, ContactMeAltText, ContactMeName, ContactMeJavaScript, ContactMeImageUrl, null, MenuItemDirection.Vertical, ContactMeTableID, false));
156
157            // create the useful links sub-menu
158            MyPopupMenu.PopupMenu[2].PopupSubMenus = new PopupMenuItemDetailsCollection();
159            MyPopupMenu.PopupMenu[2].PopupSubMenus.Add(new PopupMenuItemDetails(DeveloperLand, DeveloperLandAltText, DeveloperLandName, DeveloperLandJavaScript, DeveloperLandImageUrl, null, MenuItemDirection.Vertical, DeveloperLandTableID, false));
160            MyPopupMenu.PopupMenu[2].PopupSubMenus.Add(new PopupMenuItemDetails(CodeGuru, CodeGuruAltText, CodeGuruName, CodeGuruJavaScript, CodeGuruImageUrl, null, MenuItemDirection.Vertical, CodeGuruTableID, false));
161            MyPopupMenu.PopupMenu[2].PopupSubMenus.Add(new PopupMenuItemDetails(GotDotNet, GotDotNetAltText, GotDotNetName, GotDotNetJavaScript, GotDotNetImageUrl, null, MenuItemDirection.Vertical, GotDotNetTableID, false));
162            MyPopupMenu.PopupMenu[2].PopupSubMenus.Add(PopupMenuItemDetails.PopupMenuItemSeparator());
163            MyPopupMenu.PopupMenu[2].PopupSubMenus.Add(new PopupMenuItemDetails(Msdn, MsdnAltText, MsdnName, MsdnJavaScript, MsdnImageUrl, null, MenuItemDirection.Vertical, MsdnTableID, false));
164
165            // find the cell we use to add our content
166            Control ContentCell = BaseControl.FindControl(Controls, ControlContainer);
167
168            // event handler called when a menu item has been clicked
169            MyPopupMenu.MenuClicked += new MenuClicked(MyPopupMenu_MenuClicked);
170
171            // if we found the content cell then let's add the popup menu control to it
172            if (ContentCell != null)
173                ContentCell.Controls.Add(MyPopupMenu);
174
175            // the label which shows which menu item has been clicked
176            Message = BaseControl.CreateLabel(Controls, NoMenuItemClicked);
177            Message.CssClass = MessageStyle;
178        }

179
180        /// <summary>
181        /// event handler called when a menu item has been clicked
182        /// </summary>
183        /// <param name="Controls">the menu controls collection</param>
184        /// <param name="ClickedMenuItem">the selected menu item</param>

185        void MyPopupMenu_MenuClicked(ControlCollection Controls, MenuItemDetails ClickedMenuItem)
186        {
187            Message.Text = String.Format(ClickedMessage, ClickedMenuItem.DisplayText);
188        }
    
189    }

190}

191

PopupMenuControl.js代码:

  1
  2var VisibleSubMenus = '';
  3var MenuTimer = 0;
  4var CloseTimer = 0;
  5
  6
  7function EnterMenuCell(MenuCell,SubMenuTable)
  8{
  9    // if the sub-menu-table is not displayed at the moment
 10    if (SubMenuTable.style.display == 'none')
 11    {
 12        // then display it now
 13        SubMenuTable.style.display = '';
 14
 15        // add this to the list of visible sub-menus; this is important if the user browses
 16        // multiple cascaded sub-menus
 17        if (VisibleSubMenus.length == 0)
 18            VisibleSubMenus += SubMenuTable.id;
 19        else
 20            VisibleSubMenus += ',' + SubMenuTable.id;
 21    }

 22}

 23
 24//
 25// the user moves the mouse outside the menu cell
 26//
 27function LeaveMenuCell(MenuCell,SubMenuTable)
 28{
 29   
 30    if (MenuTimer == 0)
 31        MenuTimer = window.setInterval("CheckIfSubMenuToClose(" + SubMenuTable.id + ")"20);
 32}

 33
 34
 35function LeaveSubMenuTable(SubMenuTable)
 36{
 37    // get the list of visible sub-menus
 38    var VisibleSubMenusArray = VisibleSubMenus.split(",");
 39
 40    // get the last visible sub-menu
 41    var LastVisibleSubMenu = VisibleSubMenusArray[VisibleSubMenusArray.length - 1];
 42
 43
 44    if ((SubMenuTable.style.display != 'none') & (LastVisibleSubMenu == SubMenuTable.id))
 45    {
 46        // closes the sub-menu table
 47        CloseSubMenu(SubMenuTable);
 48
 49        
 50        if (MenuTimer == 0)
 51            MenuTimer = window.setInterval("CloseAllSubMenus()"20);
 52    }

 53}

 54
 55
 56function CloseAllSubMenus()
 57{
 58    // first clear the timer
 59    if (MenuTimer != 0)
 60    {
 61       window.clearInterval(MenuTimer);
 62       MenuTimer = 0;
 63    }

 64    
 65    // check if we have any sub-menus open
 66    if (VisibleSubMenus.length > 0)
 67    {
 68        // get the list of visible sub-menus
 69        var VisibleSubMenusArray = VisibleSubMenus.split(",");
 70
 71        // now loop through all visible sub-menus and close them too
 72        for (Count=0; Count < VisibleSubMenusArray.length; Count++)
 73        {
 74            // get a reference to the visible sub-menu
 75            var SubMenu = document.getElementById(VisibleSubMenusArray[Count]);
 76
 77            // and now hide it
 78            SubMenu.style.display = 'none';
 79        }

 80
 81        // reset the list of visible sub-menus
 82        VisibleSubMenus = '';
 83    }

 84}

 85
 86//
 87// the user moves the mosue cursor over the sub-menu table
 88//
 89function EnterSubMenuTable(SubMenuTable)
 90{
 91   
 92    if (MenuTimer != 0)
 93    {
 94        window.clearInterval(MenuTimer);
 95        MenuTimer = 0;
 96    }

 97}

 98
 99
100function CheckIfSubMenuToClose(SubMenuTable)
101{
102    // first clear the timer itself
103    if (MenuTimer != 0)
104    {
105       window.clearInterval(MenuTimer);
106       MenuTimer = 0;
107    }

108
109    // now close the sub-menu table
110    CloseSubMenu(SubMenuTable);
111}

112
113//
114// closes the sub-menu table and removes it from the list of visible sub-menus
115//
116function CloseSubMenu(SubMenuTable)
117{
118    // now close the sub-menu
119    SubMenuTable.style.display = 'none';
120
121    // get the list of visible sub-menus
122    var VisibleSubMenusArray = VisibleSubMenus.split(",");
123
124    // now we rebuild the list of visible sub-menus by excluding the sub-menu we 
125    // just closed
126    VisibleSubMenus = '';
127
128    // loop through all existing sub-menus
129    for (Count=0; Count < VisibleSubMenusArray.length; Count++)
130
131        // if the sub-menu is the same as the one we just closed then ignore it;
132        // otherwise add it again
133        if (VisibleSubMenusArray[Count] != SubMenuTable.id)
134            if (VisibleSubMenus.length > 0)
135                VisibleSubMenus += "," + VisibleSubMenusArray[Count];
136            else
137                VisibleSubMenus = VisibleSubMenusArray[Count];
138}

139
140
141function SetControlPosition(SubMenuTable,ParentTable,ParentCell,ParentMenuDirection,OffsetX,OffsetY)
142{
143    // we position the control absolute
144    SubMenuTable.style.position = 'absolute';
145
146    // parent menu is horizontal, so we position the sub-menu at left/bottom
147    if (ParentMenuDirection == 'Horizontal')
148    {
149        SubMenuTable.style.left = ParentTable.offsetLeft + ParentCell.offsetLeft - 1;
150        SubMenuTable.style.top = ParentTable.offsetTop + ParentTable.offsetHeight - 1;
151    }

152    else
153
154        // parent menu is vertical, so we position the sub-menu at right/top
155        if (ParentMenuDirection == 'Vertical')
156        {
157            SubMenuTable.style.left = ParentTable.offsetLeft + ParentTable.offsetWidth - 1;
158            SubMenuTable.style.top = ParentTable.offsetTop + ParentCell.offsetTop - 1;
159        }

160
161        // there is no parent-menu; this is a popup menu which will be positioned in the
162        // middle of the owning control
163        else
164        {
165            SubMenuTable.style.left = ParentTable.offsetLeft + (ParentTable.offsetWidth / 2+ 1 + Number(OffsetX);
166            SubMenuTable.style.top = ParentTable.offsetTop + (ParentTable.offsetHeight / 2+ 1 + Number(OffsetY);
167
168            // add any body margin we have
169            SubMenuTable.style.left = Number(SubMenuTable.style.left.replace('px','')) + Number(document.body.leftMargin);
170            SubMenuTable.style.top = Number(SubMenuTable.style.top.replace('px','')) + Number(document.body.topMargin);
171        }

172}

173
174
175function ShowPopupMenu(PopupOwnerControl,PopupTableControl,OffsetX,OffsetY)
176{
177    // position the popup menu in the middle of the owner control
178    SetControlPosition(PopupTableControl, PopupOwnerControl, null, 'popup', OffsetX, OffsetY);
179
180    // show the popup-menu
181    PopupTableControl.style.display = '';
182
183    // give the popup menu table the focus so we know when the user clicks anywhere
184    // else (the control looses then the focus
185    PopupTableControl.focus();
186}

187
188
189function ClosePopupMenu(PopupOwnerControl,PopupTableControl)
190{
191    if (CloseTimer == 0)
192        CloseTimer = window.setInterval("ClosePopupMenuDelayed(" + PopupOwnerControl.id + "," + PopupTableControl.id + ")"190);
193}

194
195
196function ClosePopupMenuDelayed(PopupOwnerControl,PopupTableControl)
197{
198    // clears first the timer
199    if (CloseTimer != 0)
200    {
201        window.clearInterval(CloseTimer);
202        CloseTimer = 0;
203    }

204
205    // we hide the popup menu
206    PopupTableControl.style.display = 'none';
207
208    // close any open sub-menu
209    CloseAllSubMenus();
210}

211

PopupMenuControl.css代码:

 1.PopupMenuTableStyle
 2{
 3    border: groove 2px white;
 4    background-color: black;
 5    position: relative;
 6    left: 0px;
 7    top: 0px;
 8}

 9.PopupMenuRowStyle
10{
11    vertical-align: middle;
12}

13.PopupMenuCellStyle
14{
15    background-color: #ececec;
16    text-align: left;
17    width: 180px;
18    height: 20px;
19}

20.PopupMenuCellHighlightedStyle
21{
22    background-color: #ccccff;
23    text-align: left;
24    width: 180px;
25    height: 20px;
26}

27.PopupMenuLinkStyle
28{
29    font: normal normal bold small/normal Arial;
30    text-decoration: none;
31    white-space: nowrap;
32    color: blue;
33    cursor: hand;
34    line-height: 18px;
35}

36.PopupMenuLinkHighlightedStyle
37{
38    font: normal normal bolder small/normal Arial;
39    text-decoration: none;
40    white-space: nowrap;
41    color: #ffffcc;
42    color: blue;
43    cursor: hand;
44    line-height: 18px;
45}

46.MenuSeparatorCellStyle
47{
48    background-color: #ececec;
49    height: 1px;
50    padding: 0px 0px 0px 0px;
51    margin: 0px 0px 0px 0px;
52}

53.MenuSeparatorStyle
54{
55    border-top: ridge 1px;
56    width: 100%;
57    color: white;
58    height: 1px;
59}

60.PopupMenuImageBarStyle
61{
62    background-color: #cccccc;
63    width: 24px;
64}

65

源码下载地址:
http://www.cnblogs.com/Files/Terrylee/PopupMenuControlSample.rar

posted @ 2005-09-30 08:54  TerryLee  阅读(...)  评论(...编辑  收藏