通常windows應用程序都有相似的特征:控件、菜單、工具條、狀態欄等等。每次我們開始作一個新的windows應用程序時都是以相同的事情開始:建立項目,添加控件和事件處理器。如果我們有一個模板,那麼我們就可以節約大量的時間了。
在介紹如何建立模板的過程中,將涉及大量的微軟.net framework類庫的基本知識。如果你沒有使用集成開發環境那麼本文介紹的模板對你將非常有用,如果你使用了visual studio.net這樣的集成開發環境你也可以從中了解控件的工作方式,這對你也是很有用的。
寫一個windows應用程序總是從下面的幾個步驟開始:
1、創建一個窗體
2、給窗體添加控件
3、添加菜單和菜單項,並綁定到窗體上
4、創建工具條
5、添加狀態欄
6、添加事件處理器
在windows應用程序開發中,你不可能完全跳過這些步驟,你可以對他作些修改,但不可能完全跳過。下面是完全的模板圖:
--------------圖1 -----------
創建窗體
在.Net FrameWork程序設計中,窗體總是System.Windows.Forms.Form類的子類,他繼承聊著各類的全部特征,你甚至不用添加任何一行代碼就可以創建window窗體了。現在我們創建一個form類的子類myapp,需要注意的是在說明繼承時使用冒號:。
using System.Windows.Forms;
public class MyWinApp: Form {
}
與其他程序相似,我們需要一個main()的主方法作為應用程序的入口。在main()中使用System.Windows.Forms的run方法來開始應用程序和顯示窗體。run方法有三種重載方式,對於windows應用程序,我們采取重載一個窗體對象的方式:
public static void Main() {
MyWinApp form = new MyWinApp();
Application.Run(form);
}
作為選擇,可以在main()方法中將兩行代碼寫成一行:
public static void Main() {
Application.Run(new MyWinApp());
}
設置屬性
一旦有了窗體,就可以設置它的屬性(象高度、寬度、標題等)並指定一個象圖1那樣的圖標,可以通過代碼或從構造器重調用一個方法來完成這個設置。在list1中有一個方法InitializeComponent,可以將初始化代碼寫入其中。
使用width和height屬性設置寬度和高度
this.Width = 400;
this.Height = 300;
使用窗體的text屬性設置標題
this.Text = "My Windows Application";
設置圖標
如果未作說明,windows應用程序將顯示一個缺省圖標,可以修改這個圖標,方法是設置窗體的icon屬性,這個屬性接受一個System.Drawing.Icon對象。Icon類有幾個可以用於初始化Icon對象的構造函數,需要說明的是最好提供.ico文件的完全路徑。
this.Icon = new Icon(imageFolder + "applicationLogo.ico");
這裡 imageFolder是一個靜態域,用於指示icon文件的目錄,imageFolder的定義如下:
static String imageFolder = "Images" +
Path.DirectorySeparatorChar.ToString();
這告訴應用程序icon文件在應用程序的image目錄下,這裡使用了System.IO.Path 類的DirectorySeparatorChar屬性獲得操作系統用於分隔目錄和父目錄的分隔符,在這裡沒有使用"/",這是因為對於windows操作系統這是正確的,但對於linux和unix則不然。這也是為了證明模板對於其他操作系統也是方便的。
窗體的位置
使窗體居中時非常有用的,要達到這個目的,需要使用StartPosition屬性,並將FormStartPosition 的一個成員賦給他。
this.StartPosition = FormStartPosition.CenterScreen;
當然也可以用form類的CenterToScreen方法是窗體居中,但這個方法不能直接使用。
this.CenterToScreen();
form類還有其他一些讓人感興趣的屬性和方法,這裡列出了其中的部分:
1、設置Opacity 屬性創建一個透明或半透明的窗體
2、設置modal屬性使窗體為模式的或非模式的
3、通過BackColor屬性改變窗體的背景顏色
4、將TopMost屬性設置為true,以確定窗體在其他所有非最頂部窗體之上
給窗體添加控件
windows控件均繼承自System.Windows.Forms.Control類,control類處理用戶輸入、安全等,他給窗體的控件提供了一個windows句柄,以及一些重要的屬性,如Name, Enabled, Text, BackColor, Left, Top, Size, Location, Visible, Width, 和 Height。
System.Windows.Forms名稱空間提供了12個控件,每一個控件都有它自己的屬性和特征,所以在篇文章中我們不可能全部討論。給窗體添加控減非常容易,下面的代碼給窗體添加了三個控件,分別是:Label, Button, 和TreeView。
Label label;
Button button;
TreeView tree;
為了簡便,可以在聲明的同時實例化這些對象。
Label label = new Label();
Button button = new Button();
TreeView tree = new TreeView();
然後在InitializeComponent方法中設置這些控件的屬性,尤其是設置控件的大小和在窗體中的位置,對於大小可以使用width和height屬性,比如treeview控件的大小可以使用下面的屬性:
tree.Width = 100;
tree.Height = 100;
確定控件的位置可以使用控件的left和top屬性,這兩個屬性決定了控件的左上角的位置,就像下面的語句決定了treeview的位置:
tree.Top = 40;
tree.Left = 20;
當然你也可以使用更簡單的Location屬性,將System.Drawing.Point結構的實例賦給他。我們用這種方法確定Label和Button的位置。
label.Location = new Point(220, 40);
button.Location = new Point(220, 80); 下一步就是要使控件在窗體上可見。使用Form.ControlCollection類的add方法將每個控件添加到窗體的ControlCollection中,ControlCollection可以使用窗體的控件屬性訪問。
this.Controls.Add(label);
this.Controls.Add(button);
this.Controls.Add(tree);
添加菜單和菜單項 要找到沒有菜單的windows應用程序非常困難,菜單使訪問應用程序的功能變得很簡單,在大多數環境下可以最小的使用控件。菜單比控件占用更少的空間,同時使應用程序顯得更有組織。
在System.Windows.Forms名稱空間中,所有與菜單相關的控件都是menu類的子類。menu是一個抽象類,你不能直接實例化,menu類有三個子類:
ContextMenu
MainMenu
MenuItem
ContextMenu類表示快捷菜單,在控件或窗體區域點擊鼠標右鍵時顯示。快捷菜單常用於組合窗體mainmenu類的菜單項給出應用程序的上下文,這對於用戶時非常有用的。
MainMenu表示傳統的位於窗體頂部的菜單,你可以把它看成窗體菜單結構的容器。一個菜單是由MenuItem表示的菜單項組成的,對於應用程序而言每一個菜單項是一個命令或其它子菜單項的父菜單。form類都有一個menu屬性,采用將mainmenu對象賦給menu屬性的方式將mainmenu對象綁定到窗體。
在這個模板中,我們沒有使用ContextMenu類,但我們示范了如何使用MainMenu和MenuItem類。我們首先需要在窗體中添加一個菜單,給窗體添加一個MainMenu對象。
MainMenu mainMenu = new MainMenu();
現在MainMenu對象中什麼都沒有,下面我們給他添加一個MenuItem對象。在List1中主菜單稱為fileMenuItem,它的text屬性是&File,&表示他後面的字母帶下劃線,是該菜單的快捷鍵。通過使用Menu對象的MenuItemCollection的add方法為MainMenu添加一個或幾個MenuItem,這個集合可以通過menu類的MenuItems屬性訪問。
MenuItem fileMenuItem = new MenuItem();
mainMenu.MenuItems.Add(fileMenuItem);
我們在fileMenuItem 菜單項中還添加了其它MenuItem,這些MenuItem是fileMenuItem的子菜單。你也可以給子菜單添加子菜單。圖2顯示了菜單的等級結構。
---------圖2---------
菜單項的聲明如下:
MenuItem fileNewMenuItem;
MenuItem fileOpenMenuItem;
MenuItem fileSaveMenuItem;
MenuItem fileSaveAsMenuItem;
MenuItem fileMenuWithSubmenu;
MenuItem submenuMenuItem;
MenuItem fileExitMenuItem;
MenuItem類有幾個構造函數,使用這些構造函數實例化你的 MenuItem對象,並添加一個事件處理器。
// the following constructor is the same as:
// menuItem fileNewMenuItem = new MenuItem();
// fileNewMenuItem.Text = "&New";
// fileNewMenuItem.Shortcut = Shortcut.CtrlN;
// fileNewMenuItem.Click += new
// System.EventHandler(this.fileNewMenuItem_Click);
fileNewMenuItem = new MenuItem("&New",
new System.EventHandler(this.fileNewMenuItem_Click), Shortcut.CtrlN);
fileOpenMenuItem = new MenuItem("&Open",
new System.EventHandler(this.fileOpenMenuItem_Click), Shortcut.CtrlO);
fileSaveMenuItem = new MenuItem("&Save",
new System.EventHandler(this.fileSaveMenuItem_Click), Shortcut.CtrlS);
fileSaveAsMenuItem = new MenuItem("Save &As",
new System.EventHandler(this.fileSaveAsMenuItem_Click));
fileMenuWithSubmenu = new MenuItem("&With Submenu");
submenuMenuItem = new MenuItem("Su&bmenu",
new System.EventHandler(this.submenuMenuItem_Click));
fileExitMenuItem = new MenuItem("E&xit",
new System.EventHandler(this.fileExitMenuItem_Click));
Event handling is discussed further in the section "Adding Event Handlers."
As mentioned, the menu items are added to the fileMenuItem control.
fileMenuItem.MenuItems.Add(fileNewMenuItem);
fileMenuItem.MenuItems.Add(fileOpenMenuItem);
fileMenuItem.MenuItems.Add(fileSaveMenuItem);
fileMenuItem.MenuItems.Add(fileSaveAsMenuItem);
fileMenuItem.MenuItems.Add(fileMenuWithSubmenu);
fileMenuWithSubmenu.MenuItems.Add(submenuMenuItem);
fileMenuItem.MenuItems.Add("-"); // add a separator
fileMenuItem.MenuItems.Add(fileExitMenuItem);
注意在菜單項之間可以創建一個分隔符,方法是使用menu類的MenuItems集合的add方法。上面的例子中使用的分隔符是"-"。
創建工具條
為了使應用程序的界面更友好,可以在窗體中添加一個工具條。工具條由System.Windows.Forms.ToolBar類描述。窗體中可有多個工具條,工具條中包含了一個或多個ToolBarButton類描述的按鈕,可以在每個按鈕中插入圖像或圖標,要達到這個目的你需要一個ImageList控件作為圖像容器。
ImageList imageList = new ImageList();
對於每個圖像文件首先要實例化為image對象,然後將這些圖像添加到ImageList控件中,Image和Bitmap類可以在System.Drawing名稱空間中找到。
Image newFileImage = new Bitmap(imageFolder + "newFile.bmp");
Image openFileImage = new Bitmap(imageFolder + "openFile.gif");
Image saveFileImage = new Bitmap(imageFolder + "saveFile.bmp");
Image printImage = new Bitmap(imageFolder + "print.gif");
.
.
.
imageList.Images.Add(newFileImage);
imageList.Images.Add(openFileImage);
imageList.Images.Add(saveFileImage);
imageList.Images.Add(printImage);
注意你可以使用Images集合的add方法將image對象加入到imagelist控件中。現在為將這些圖加入到控件中,必須將ImageList控件賦給ToolBar的ImageList屬性。
toolBar.ImageList = imageList;
然後將ImageList控件中的圖像賦給工具按鈕的ImageIndex屬性。
newToolBarButton.ImageIndex = 0;
openToolBarButton.ImageIndex = 1;
saveToolBarButton.ImageIndex = 2;
printToolBarButton.ImageIndex = 3;
象菜單項一樣,現在必須把工具按鈕加入到工具條中。
toolBar.Buttons.Add(separatorToolBarButton);
toolBar.Buttons.Add(newToolBarButton);
toolBar.Buttons.Add(openToolBarButton);
toolBar.Buttons.Add(saveToolBarButton);
toolBar.Buttons.Add(separatorToolBarButton);
toolBar.Buttons.Add(printToolBarButton);
最後將工具條加入到窗體中。
this.Controls.Add(toolBar);
添加狀態條 狀態條由System.Windows.Forms.StatusBar描述,它提供了定制控件的外觀的屬性,狀態條由StatusBarPanel對象組成,在我們的模板中狀態條有兩個嵌套板:
StatusBar statusBar = new StatusBar();
StatusBarPanel statusBarPanel1 = new StatusBarPanel();
StatusBarPanel statusBarPanel2 = new StatusBarPanel();
狀態條和狀態跳上的嵌套板由下面的代碼設置:
statusBarPanel1.BorderStyle = StatusBarPanelBorderStyle.Sunken;
statusBarPanel1.Text = "Press F1 for Help";
statusBarPanel1.AutoSize = StatusBarPanelAutoSize.Spring;
statusBarPanel2.BorderStyle = StatusBarPanelBorderStyle.Raised;
statusBarPanel2.ToolTipText = System.DateTime.Now.ToShortTimeString();
statusBarPanel2.Text = System.DateTime.Today.ToLongDateString();
statusBarPanel2.AutoSize = StatusBarPanelAutoSize.Contents;
statusBar.ShowPanels = true;
statusBar.Panels.Add(statusBarPanel1);
statusBar.Panels.Add(statusBarPanel2);
同樣我們需要將狀態條添加到窗體中:
this.Controls.Add(statusBar);
事件處理器 在windows程序設計中添加事件處理器是最重要的任務。事件處理器保證了程序與用戶交互,同時完成其他重要的功能。在c#中你可以給控件和菜單事件添加事件處理器以俘獲你想處理的事件,下面的代碼給Button控件的click事件設計了一個事件處理器:
button.Click += new System.EventHandler(this.button_Click);
button_Click事件處理器必須被處理:
private void button_Click(Object sender, System.EventArgs e) {
MessageBox.Show("Thank you.", "The Event Information");
}
MenuItem 對象在實例化的同時可以給賦以一個事件處理器:
fileNewMenuItem = new MenuItem("&New",
new System.EventHandler(this.fileNewMenuItem_Click), Shortcut.CtrlN);
fileOpenMenuItem = new MenuItem("&Open",
new System.EventHandler(this.fileOpenMenuItem_Click), Shortcut.CtrlO);
fileSaveMenuItem = new MenuItem("&Save",
new System.EventHandler(this.fileSaveMenuItem_Click), Shortcut.CtrlS);
fileSaveAsMenuItem = new MenuItem("Save &As",
new System.EventHandler(this.fileSaveAsMenuItem_Click));
fileMenuWithSubmenu = new MenuItem("&With Submenu");
submenuMenuItem = new MenuItem("Su&bmenu",
new System.EventHandler(this.submenuMenuItem_Click));
fileExitMenuItem = new MenuItem("E&xit",
new System.EventHandler(this.fileExitMenuItem_Click));
你不能給工具按鈕指派一個事件處理器,但可以給工具條指派一個事件處理器:
toolBar.ButtonClick += new
ToolBarButtonClickEventHandler(this.toolBar_ButtonClick);
protected void toolBar_ButtonClick(Object sender, ToolBarButtonClickEventArgs
e) {
// Evaluate the Button property to determine which button was clicked.
switch (toolBar.Buttons.IndexOf(e.Button)) {
case 1:
MessageBox.Show("Second button.", "The Event Information");
break;
case 2:
MessageBox.Show("third button", "The Event Information");
break;
case 3:
MessageBox.Show("fourth button.", "The Event Information");
break;
}
}
例子中也給窗體的close事件設計了一個事件處理器,通過重載OnClosing方法你可以接收用戶點擊窗體的X按鈕,這樣你可以取消關閉事件:
protected override void OnClosing(CancelEventArgs e) {
MessageBox.Show("Exit now.", "The Event Information");
}
現在我們的模板就完成了,你可以使用他開始你的WINDOWS應用程序設計。
附錄 Listing 1. C# Windows 應用程序模板
/*
to compile this source file, type
csc MyWinApp.cs
*/
using System;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.ComponentModel;
public class MyWinApp: Form {
Label label = new Label();
Button button = new Button();
TreeView tree = new TreeView();
ImageList imageList = new ImageList();
static String imageFolder = "Images" +
Path.DirectorySeparatorChar.ToString();
// -------------- Images declarations ------------------------------------
Image newFileImage = new Bitmap(imageFolder + "newFile.bmp");
Image openFileImage = new Bitmap(imageFolder + "openFile.gif");
Image saveFileImage = new Bitmap(imageFolder + "saveFile.bmp");
Image printImage = new Bitmap(imageFolder + "print.gif");
// -------------- End of Images declaration
------------------------------------
// -------------- menu ------------------------------------
MainMenu mainMenu = new MainMenu();
MenuItem fileMenuItem = new MenuItem();
MenuItem fileNewMenuItem;
MenuItem fileOpenMenuItem;
MenuItem fileSaveMenuItem;
MenuItem fileSaveAsMenuItem;
MenuItem fileMenuWithSubmenu;
MenuItem submenuMenuItem;
MenuItem fileExitMenuItem;
// -------------- End of menu ------------------------------------
// -------------- Toolbar ------------------------------------
ToolBar toolBar = new ToolBar();
ToolBarButton separatorToolBarButton = new ToolBarButton();
ToolBarButton newToolBarButton = new ToolBarButton();
ToolBarButton openToolBarButton = new ToolBarButton();
ToolBarButton saveToolBarButton = new ToolBarButton();
ToolBarButton printToolBarButton = new ToolBarButton();
// -------------- End of Toolbar ------------------------------------
// -------------- StatusBar ------------------------------------
StatusBar statusBar = new StatusBar();
StatusBarPanel statusBarPanel1 = new StatusBarPanel();
StatusBarPanel statusBarPanel2 = new StatusBarPanel();
// -------------- End of StatusBar ------------------------------------
public MyWinApp() {
InitializeComponent();
}
private void InitializeComponent() {
this.Text = "My Windows Application";
this.Icon = new Icon(imageFolder + "applicationLogo.ico");
this.Width = 400;
this.Height = 300;
this.StartPosition = FormStartPosition.CenterScreen;
imageList.Images.Add(newFileImage);
imageList.Images.Add(openFileImage);
imageList.Images.Add(saveFileImage);
imageList.Images.Add(printImage);
// menu
fileMenuItem.Text = "&File";
// the following constructor is the same as:
// menuItem fileNewMenuItem = new MenuItem();
// fileNewMenuItem.Text = "&New";
// fileNewMenuItem.Shortcut = Shortcut.CtrlN;
// fileNewMenuItem.Click += new
System.EventHandler(this.fileNewMenuItem_Click);
fileNewMenuItem = new MenuItem("&New",
new System.EventHandler(this.fileNewMenuItem_Click), Shortcut.CtrlN);
fileOpenMenuItem = new MenuItem("&Open",
new System.EventHandler(this.fileOpenMenuItem_Click), Shortcut.CtrlO);
fileSaveMenuItem = new MenuItem("&Save",
new System.EventHandler(this.fileSaveMenuItem_Click), Shortcut.CtrlS);
fileSaveAsMenuItem = new MenuItem("Save &As",
new System.EventHandler(this.fileSaveAsMenuItem_Click));
fileMenuWithSubmenu = new MenuItem("&With Submenu");
submenuMenuItem = new MenuItem("Su&bmenu",
new System.EventHandler(this.submenuMenuItem_Click));
fileExitMenuItem = new MenuItem("E&xit",
new System.EventHandler(this.fileExitMenuItem_Click));
mainMenu.MenuItems.Add(fileMenuItem);
fileOpenMenuItem.Checked = true;
fileMenuItem.MenuItems.Add(fileNewMenuItem);
fileMenuItem.MenuItems.Add(fileOpenMenuItem);
fileMenuItem.MenuItems.Add(fileSaveMenuItem);
fileMenuItem.MenuItems.Add(fileSaveAsMenuItem);
fileMenuItem.MenuItems.Add(fileMenuWithSubmenu);
fileMenuWithSubmenu.MenuItems.Add(submenuMenuItem);
fileMenuItem.MenuItems.Add("-"); // add a separator
fileMenuItem.MenuItems.Add(fileExitMenuItem);
toolBar.Appearance = ToolBarAppearance.Normal;
//toolBar.Appearance = ToolBarAppearance.Flat;
toolBar.ImageList = imageList;
toolBar.ButtonSize = new Size(14, 6);
separatorToolBarButton.Style = ToolBarButtonStyle.Separator;
newToolBarButton.ToolTipText = "New Document";
newToolBarButton.ImageIndex = 0;
openToolBarButton.ToolTipText = "Open Document";
openToolBarButton.ImageIndex = 1;
saveToolBarButton.ToolTipText = "Save";
saveToolBarButton.ImageIndex = 2;
printToolBarButton.ToolTipText = "Print";
printToolBarButton.ImageIndex = 3;
toolBar.ButtonClick += new
ToolBarButtonClickEventHandler(this.toolBar_ButtonClick);
toolBar.Buttons.Add(separatorToolBarButton);
toolBar.Buttons.Add(newToolBarButton);
toolBar.Buttons.Add(openToolBarButton);
toolBar.Buttons.Add(saveToolBarButton);
toolBar.Buttons.Add(separatorToolBarButton);
toolBar.Buttons.Add(printToolBarButton);
tree.Top = 40;
tree.Left = 20;
tree.Width = 100;
tree.Height = 100;
label.Location = new Point(220, 40);
label.Size = new Size(160, 30);
label.Text = "Yes, click the button";
button.Location = new Point(220, 80);
button.Size = new Size(100, 30);
button.Text = "Click this";
button.Click += new System.EventHandler(this.button_Click);
statusBarPanel1.BorderStyle = StatusBarPanelBorderStyle.Sunken;
statusBarPanel1.Text = "Press F1 for Help";
statusBarPanel1.AutoSize = StatusBarPanelAutoSize.Spring;
statusBarPanel2.BorderStyle = StatusBarPanelBorderStyle.Raised;
statusBarPanel2.ToolTipText = System.DateTime.Now.ToShortTimeString();
statusBarPanel2.Text = System.DateTime.Today.ToLongDateString();
statusBarPanel2.AutoSize = StatusBarPanelAutoSize.Contents;
statusBar.ShowPanels = true;
statusBar.Panels.Add(statusBarPanel1);
statusBar.Panels.Add(statusBarPanel2);
this.Menu = mainMenu;
this.Controls.Add(toolBar);
this.Controls.Add(tree);
this.Controls.Add(label);
this.Controls.Add(button);
this.Controls.Add(statusBar);
}
// -------------- Event Handlers --------------------------
private void fileNewMenuItem_Click(Object sender, EventArgs e) {
MessageBox.Show("You clicked the File -- New menu.", "The Event
Information");
}
private void fileOpenMenuItem_Click(Object sender, EventArgs e) {
MessageBox.Show("You clicked the File -- Open menu.", "The Event
Information");
}
private void fileSaveMenuItem_Click(Object sender, EventArgs e) {
MessageBox.Show("You clicked the File -- Save menu.", "The Event
Information");
}
private void fileSaveAsMenuItem_Click(Object sender, EventArgs e) {
MessageBox.Show("You clicked the File -- Save As menu.", "The Event
Information");
}
private void fileExitMenuItem_Click(Object sender, EventArgs e) {
MessageBox.Show("You clicked the File -- Exit As menu.", "The Event
Information");
}
private void submenuMenuItem_Click(Object sender, EventArgs e) {
MessageBox.Show("You clicked the submenu.", "The Event Information");
}
protected void toolBar_ButtonClick(Object sender,
ToolBarButtonClickEventArgs e) {
// Evaluate the Button property to determine which button was clicked.
switch (toolBar.Buttons.IndexOf(e.Button)) {
case 1:
MessageBox.Show("Second button.", "The Event Information");
break;
case 2:
MessageBox.Show("third button", "The Event Information");
break;
case 3:
MessageBox.Show("fourth button.", "The Event Information");
break;
}
}
protected override void OnClosing(CancelEventArgs e) {
MessageBox.Show("Exit now.", "The Event Information");
}
private void button_Click(Object sender, System.EventArgs e) {
MessageBox.Show("Thank you.", "The Event Information");
}
// -------------- End of Event Handlers -------------------
public static void Main() {
MyWinApp form = new MyWinApp();
Application.Run(form);
} }