用C#和VB.NET實現VS.NET或Office XP風格的菜單
小氣的神 2001.08.18
VS.NET或Office XP中的菜單都是非常漂亮的,反正我很喜歡。可惜VS.NET沒有帶制作這種菜單的控件或組件,不知正式版本會不會提供一個模板和向導。至今還記得剛學計算機語言時自己用Turbo C制作菜單的感受,那些矩形框函數和象素操作的確很迷人,況且那時是如此的流行菜單。
這篇文章中我會介紹有關在Framework SDK Beta 2 中制作自己風格的菜單,所以你最好已安裝了Framework SDK Beta 2,VS.NET Beta 2 不一定是必須的。附帶的Zip包中的例子都是VS.NET Project的。
整個的文章包括三部分:
開始我會涉及到在Winform中最基本的一些菜單的概念。
然后會有一個以前接觸過的有關菜單的例子,它是For Beta 1的。老實說我沒有想到Beta1 到Beta2有許多函數和命名空間發生了變化,以前我在Beta1中測試過這個例子,很順利。這次在Beta2中會有許多錯誤,我提供了兩個Project,一個是原來的Project的,一個是我修改后For Beta 2的。這種移植很枯燥,但可以很快熟悉新的Beta2的類庫和函數,Show出來的菜單還不錯,感覺是Office2000風格的菜單。如果你有興趣可以試一試這個過程,會獲益非淺的,這個例子還包括按鈕的,原來的作者其實是在Demo控件的“Owner-drawn menus”技術;不過我只對菜單部分感興趣。
最后一部分是制作VS.NET或XP風格的例子,上面那個例子的效果不能使我完全滿意,然后我重新寫了另外一個,不過我對最后的結果還不是很滿意,因為我的沒有上一個例子那么完整,例子中我只顯示了這個風格的菜單,對于事件響應、狀態欄更新、tooltips、菜單的狀態(enabled state)等處理都沒有考慮,我把這些歸結為時間問題,并承諾自己下次把它做得更好。
1.Framework SDK Beta 2中菜單分成兩類一類是普通的菜單叫:MainMenu,在VS.NET的Toolsbox中有這樣一個對應的菜單控件,拖下它到你的窗體中,設置一下屬性就可以所見所得了,這個版本的比VS.Studio98 系列的要好用和漂亮的多。另一類叫:ContextMenu菜單,也就是常用的彈出菜單。對于VB6來說所有的普通菜單在VS.NET中是可以兼容和自動升級成MainMenu類型的菜單,但對于PopMenu的菜單是不能轉換成ContextMenu類型的菜單,你必須自己重新修改代碼實現。這里我們主要是針對MainMenu的,其實原理一樣。
最簡單的菜單你可以這樣做:
using System;
using System.Windows.Forms;
public class frmVB6 : Form {
private MainMenu muMain ; // MainMenu
public static int Main(string[] Args) {
Application.Run(new frmVB6());
return 0;
}
public frmVB6() {
// The following code sets up the form properties.
this.Text = "Form1";
this.Height = 213 + SystemInformation.CaptionHeight;
this.Width = 312;
this.StartPosition = FormStartPosition.WindowsDefaultLocation;
MenuItem mItemFile = new MenuItem() ;
mItemFile.Text = "&File" ;
MenuItem mItemExit = new MenuItem() ;
mItemExit.Text = "E&xit" ;
muMain = new MainMenu() ;
muMain.MenuItems.Add( mItemFile ) ;
muMain.MenuItems.Add( mItemExit) ;
this.Menu = muMain ;
}
}
手工方式保存它為一個.cs文件然后在編譯它:
csc /t:winexe /r:System.dll /r:System.Windows.Forms.Dll /r:System.Drawing.Dll Form1Menu.cs
VS.NET下只用New一個新的WinForm項目,然后在默認窗體中放入MainMenu控件,然后設置完屬性,F5就可以了,完全不用一行代碼。
如果要生成一個主菜單和一個菜單的子菜單項目,主要是MenuItems.AddRange的方法,看下面的代碼:
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.menuItem3 = new System.Windows.Forms.MenuItem();
this.menuItem4 = new System.Windows.Forms.MenuItem();
// mainMenu1
this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1, this.menuItem2});
// menuItem1
this.menuItem1.Index = 0;
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem3, this.menuItem4});
this.menuItem1.Index = 0 ;
this.menuItem1.Text = "&File";
// menuItem2
this.menuItem2.Index = 1;
this.menuItem2.Text = "Help";
// menuItem3
this.menuItem3.Index = 0;
this.menuItem3.Text = "Open";
this.menuItem3.Click += new System.EventHandler(this.menuItem3_Click);
// menuItem4
this.menuItem4.Index = 1;
this.menuItem4.Text = "Exit";
this.menuItem4.Click += new System.EventHandler(this.menuItem4_Click);
this.Menu = this.mainMenu1;
如代碼所示MenuItem1(File)和MenuItem2(Help)被AddRange到MainMenu1中成為了頂級的菜單,MenuItem3(Open)和MenuItem4(Exit)被AddRange到MenuItem1(File)中成為了File菜單下的子菜單項。
this.menuItem3.Click += new System.EventHandler(this.menuItem3_Click);表明MenuItem3點擊時激發的事件處理程序,一般的事件處理程序象下面這樣:
private void menuItem3_Click(object sender, System.EventArgs e)
{
MessageBox.Show ( " My Click Open" ) ;
}
我們關心的其實是MenuItem,讓它用我們的方式畫出有VS.NET或XP風格的菜單就可以了,更簡單的說就是實現一個MenuItem的繼承類,擴展它Draw的部分。好吧,讓我們深入一點看看第二部分。
|