使用Microsoft.NET Frameworks建立Windows應用程式

來源:互聯網
上載者:User
window|程式|建立


使用 Microsoft.NET Frameworks 建立基於 Windows 的應用程式
Shawn Burke
Microsoft Corporation
2000年9月

摘要: :本文介紹了 Win 表單這一新的表單程式包,藉助這一程式包,開發人員能夠充分利用 Microsoft Windows 作業系統所提供的 UI 功能。

目錄

簡介
介紹 Win Forms
更好的易學易用性
布局
GDI+
訪問底層系統
結論

--------------------------------------------------------------------------------

簡介

目前 Web 已成了街談巷議的話題,看起來好像 Microsoft® Visual Studio® 開發系統對建立基於 Microsoft Windows® 的傳統應用程式的支援有所減弱。實際上,Microsoft 對基於 Windows 的應用程式開發方面的投資在不斷加大。

Win 表單是一個新的表單程式包,藉助這一程式包,開發人員能夠充分利用 Microsoft Windows® 作業系統所提供的豐富的使用者介面功能,建立基於 Windows 的應用程式。Win Forms 是新的 Microsoft®.NET 平台的一個組成部分,它提供了許多新技術,包括通用的應用程式架構、可管理的執行環境、一體化的安全性以及物件導向的設計原則。而且,Win Forms 全面支援快速簡便地接入 Web Services 以及建立豐富的基於 ADO+ 資料模型的資料感知應用程式。得益於 Visual Studio 中新的共用開發環境,開發人員能夠使用包括 Microsoft Visual Basic® 和 C# 在內的任何支援 .NET 平台的語言建立 Win Forms 應用程式。

介紹 Win Forms

就像剛才所說的,Win Forms 是專用於 Windows 客戶機 UI 編程的 .NET Framework 的命名空間。它與 ASP+ UI 程式包(即 Web Forms)共用同樣的設計原則,但其類和實現卻全然不同。在 Microsoft Win32® API 和 Web 元件之間沒有魔術般變形的類。就像所有的 .NET Frameworks 一樣,一致性已成為優先考慮的問題。其目的是為了 Win Forms 開發人員能夠迅速適應在 Web Forms 中編寫代碼,反之亦然。例如,所有命名空間都有 Button 類,每一個都有文本、預設的 OnClick 事件以及 ForeColor、BackColor 和 Font 屬性。

Win Forms 的所有控制項都基於 System.WinForms.Control 類。Control 已內建了所有基本的 HWND 功能,並且它能處理我們已經熟悉並喜愛的絕大多數通用 WM_xxxx 訊息。RichControl 由 Control 派生而來,其中添加了布局邏輯和繪圖代碼。System.WinForms 命名空間中的絕大多數控制項實際上都由 RichControl 派生而來。ScrollableControl 能夠支援視窗用戶端區域的滾動。一般情況下,對滾動功能的支援是通過 ContainerControl 實現的,後者由 ScrollableControl 派生而來,並增加了對管理子控制項、焦點問題和跨欄的支援。Form 由 ContainerControl 派生而來,是 Win Form 的頂級控制項,它帶有控制標題列、系統功能表、非矩形視窗和預設控制項的屬性。UserControl 也由 ContainterControl 派生而來,是開發人員能夠建立的控制項的基本類。UserControl 一般用於託管其它子控制項,但對於外部客戶機來說,它又是作為單個單元出現的。UserControl 和 Form 在 Microsoft® Visual Studio.NET 中都有可視設計器,您會找到用於添加和設計由其所派生的類的項。

圖 1. Win Forms 控制項階層

既然我們已瞭解 Win Forms 的(最)基本方面,讓我們揭開它的面紗,看看其表面下的一些相當不錯的功能。

更好的易學易用性

Win Forms 的主要目的是儘可能地提高定位到 Win32 平台的開發人員的工作效率。無論是圖形裝置介面 (GDI) 還是視窗狀態管理,為 Win32 編程通常都是很困難的。例如,類似 WS_BORDER 或 WS_CAPTION 的一些視窗樣式只能在建立視窗時指定或修改。而 WS_VISIBLE 或 WS_CHILD 等其它視窗樣式則可以對已建立的視窗進行修改。Win Forms 儘力消除了這些細微的差別,並確保操作過程始終保持一致性。可以隨時地、不限次序地對 Win Forms 控制項的屬性進行設定,總能產生預期效果。如果改動過程需要建立新的 HWND,Win Forms 架構能夠自動地、透明地重建視窗,並為其應用相適宜的所有設定。

由控制項獲得通知或事件在 Win Forms 中也要容易得多。Win Forms 事件都基於稱為 Delegates 的一個通用語言運行時功能。Delegates 從本質上講是對型別安全的、可靠的函數指標。對於任一控制項的任一事件,都可以添加代理處理常式;絕不會強迫您建立衍生類別以通過替代處理事件,建立事件映射,或僅為處理一個事件而為類的所有事件實施一個介面。也可以通過替代衍生類別處理事件,但這種方式一般用於控制項建立者或更為進階的應用。彙集某一按鈕的 Click 事件相當簡單:

public class ButtonClickForm: System.WinForms.Form {
private System.WinForms.Button button1;
public ButtonClickForm() {
// 建立按鈕
button1 = new System.WinForms.Button();
// 添加處理常式
button1.AddOnClick(new System.EventHandler(button1_Click));
// 將按鈕添加到表單中
this.Controls.Add(button1);
}

private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("button1 clicked!");
}
}

這裡,我們建立了一個按鈕,並添加了一個名為 button1_Click 的處理常式方法,通過短短几行代碼,在單擊該按鈕後,將調用這一方法。請注意,即使處理常式方法被標記為專用,建立這一掛鈎的代碼仍可以使用該方法,單擊按鈕後,按鈕將能夠啟用這一方法的事件。

啟動 Win Forms 項目的過程也得到了簡化。使用 Visual Studio.NET 建立 Win Forms 項目的過程只會建立一個要編譯的專案檔:Form1.cs。沒有標頭檔,沒有介面定義檔案,沒有引導程式檔案,沒有資源檔,沒有庫檔案。項目所需的所有資訊都包含在表單的代碼中。這樣做有一個好處:項目由一個簡單的單表單應用程式擴充到複雜的、帶有多個代碼檔案的多表單應用程式要方便得多。連結過程不需要中間對象檔案,只有代碼和已構建的、受管理的所有 DLL。只要您習慣了這一方法,就能明顯地感覺到建立 .NET Framework 應用程式和建立 C/C++ 應用程式之間複雜性的不同。因為資訊僅僅包含在代碼檔案中,在 Visual Studio.NET 環境外建立版本的過程也非常容易,無論是 Visual Basic 代碼、C# 代碼,還是任何其它語言編寫的針對 .NET Framework 的代碼。

因為 Win Forms 建立在通用語言運行時的基礎之上,開發人員可以任選目前針對通用語言運行時的眾多語言中的一種,構建 Win32 應用程式。開發人員現在可以使用多種語言編寫 Win Forms 應用程式(或 Web Forms 應用程式或 Data 應用程式):從 C# 到 COBOL 到 Eiffel 再到 Perl 等等,中間還有很多種(上一次計數是 17 種)。方便易用再加上廣泛的應用場合相得益彰,為開發人員提供了深厚的基礎,使他們能夠迅速有效地使用 Win Forms 構建實用的應用程式。

布局

如果您曾嘗試建立能夠正常調整大小的表單,您就會知道這一過程有多麼困難。Microsoft Foundation Classes (MFC) 或早期的 Visual Basic 版本沒有對這一功能提供內建的支援。然而現在只需幾行代碼(通常情況下您甚至不需要編寫這些代碼,因為在設計時就能通過 Property Browser 實現這些功能!),即可建立能夠正常調整大小的對話方塊。

基本布局由兩條組成:Anchoring 和 Docking。RichControl 有一個 Anchor 屬性,它是一種枚舉類型,可以用“或”操作將這些值組合在一起,以說明控制項將與其父控制項的某一邊保持恒定距離。例如,如果您將一個按鈕置於表單上,並將 Anchor 屬性設定為 AnchorStyles.BottomRight,則在調整按鈕的大小時,按鈕將與表單的底邊和右邊保持同一距離。此外,如果將 Anchor 設定為 AnchorStyles.All,則按鈕的各個邊都與表單的對應邊保持同一距離,在調整按鈕大小時仍要滿足這些約束條件。

Docking 實際上是 Anchoring 的一個特殊情況。RichControl 的 Dock 屬性說明控制項要將自身固定到其父控制項的哪一邊。Docking 可以是 Top、Left、Right、Bottom 或 Fill。在每種情況下,控制項都將移動到盡量靠近指定邊,並調整其大小,以填滿那一邊。如果父控制項的大小有所調整,這一狀況仍將保持。將一個控制項移動到父控制項的底端,並將 Anchor 設定為 AnchorStyle.BottomLeftRight,可以類比 Docking Bottom。在此處的樣本中,列表框是 Docked Left,按鈕與表單的頂端、左邊和右邊保持恒定距離,由此它們保持了相對位置和大小。下面的樣本對話方塊(圖 2)完全使用 Visual Studio.NET 中的 Win Forms 設計器建立,只花了兩分鐘的時間,沒有編寫一行代碼。

圖 2. 使用 Win Forms 設計器所建立的可調整大小的對話方塊

// ResizableSample.cs
namespace ResizableSampleNamespace {

using System;
using System.Drawing;
using System.ComponentModel;
using System.WinForms;

/// <summary>
/// ResizableSample 的摘要說明。
/// </summary>
public class ResizableSample : System.WinForms.Form {
/// <summary>
/// 為 Win Forms 設計器所要求
/// </summary>
private System.ComponentModel.Container components;
private System.WinForms.Button button3;
private System.WinForms.Button button2;
private System.WinForms.Button button1;
private System.WinForms.ListBox listBox1;
public ResizableSample() {
// 為 Win Form 設計器支援所要求
InitializeComponent();

}

/// <summary>
/// 釋放正在使用的所有資源
/// </summary>
public override void Dispose() {
base.Dispose();
components.Dispose();
}

/// <summary>
/// 應用程式的主進入點。
/// </summary>
public static void Main(string[] args) {
Application.Run(new ResizableSample());
}

/// <summary>
/// 設計器支援所要求的方法 — 不要用編輯器
/// 修改這一方法的內容
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.button2 = new System.WinForms.Button();
this.button3 = new System.WinForms.Button();
this.button1 = new System.WinForms.Button();
this.listBox1 = new System.WinForms.ListBox();
//@design this.TrayLargeIcon = false;
//@design this.TrayHeight = 0;
this.Text = "Resizable Dialog";
this.IMEMode = System.WinForms.IMEMode.Off;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(256, 173);
button2.Location = new System.Drawing.Point(152, 60);
button2.Size = new System.Drawing.Size(92, 32);
button2.TabIndex = 2;
button2.Anchor = System.WinForms.AnchorStyles.TopLeftRight;
button2.Text = "Cancel";
button3.Location = new System.Drawing.Point(152, 120);
button3.Size = new System.Drawing.Size(92, 44);
button3.TabIndex = 3;
button3.Anchor = System.WinForms.AnchorStyles.All;
button3.Text = "Filler";
button1.Location = new System.Drawing.Point(152, 8);
button1.Size = new System.Drawing.Size(92, 32);
button1.TabIndex = 1;
button1.Anchor = System.WinForms.AnchorStyles.TopLeftRight;
button1.Text = "OK";
listBox1.Size = new System.Drawing.Size(120, 173);
listBox1.Dock = System.WinForms.DockStyle.Left;
listBox1.TabIndex = 0;
listBox1.Items.All = new object[] {"Item One",
"Item Two",
"Item Three",
"Item Four"};
this.Controls.Add(button3);
this.Controls.Add(button2);
this.Controls.Add(button1);
this.Controls.Add(listBox1);
}

}
}

GDI+

Win Forms 全面利用了 GDI+ 這一 Microsoft 下一代的二維圖形系統。Win Forms 中的圖形編程模式完全是物件導向的,各式各樣的畫筆、筆刷、映像和其它繪圖物件與 .NET Framework 的其它部分一樣,遵循了簡單易用的指導方針。開發人員目前可以使用相當不錯的一些繪圖新功能,如 alpha 混色、漸層色、紋理、消除鋸齒以及採用除位元影像外的其它映像格式。與 Windows 2000 作業系統分層和透明的視窗功能配合使用,開發人員能夠毫不費力地建立豐富的、更為圖形化的 Win32 應用程式。

如果觸發了控制項的 OnPaint 事件,能夠由 PaintEventArgs 訪問的 System.Drawing.Graphics 對象就成為一個 GDI+ 繪圖物件。繪圖物件能夠執行的所有操作都通過 GDI+ 實施。作為一個樣本,使用 GDI+ 建立一個繪製漸層背景的按鈕。

圖 3. 使用 GDI+ 建立的按鈕

以下是實現這一按鈕的代碼:

public class GradientButton : Button {
// 保留顏色設定的成員
private Color startColor;
private Color endColor;

// 書寫文字時我們將需要它
private static StringFormat format = new StringFormat();
public GradientButton() : base() {
// 初始化顏色
startColor = SystemColors.InactiveCaption;
endColor = SystemColors.ActiveCaption;
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
}

/// <summary>
/// 漸層色的終止顏色
// </summary>
public Color EndColor {
get {
return this.endColor;
}
set {
this.endColor = value;
// 如有必要,則導致重新繪製
if (this.IsHandleCreated && this.Visible) {
Invalidate();
}
}
}

/// <summary>
/// 漸層色的起始顏色
// </summary>
public Color StartColor {
get {
return this.startColor;
}
set {
this.startColor = value;
// 如有必要,則導致重新繪製
if (this.IsHandleCreated && this.Visible) {
Invalidate();
}
}
}

protected override void OnPaint(PaintEventArgs pe) {
// 繪製按鈕的常規背景以形成
// 邊框,等等。
base.OnPaint(pe);
Graphics g = pe.Graphics;
Rectangle clientRect = this.ClientRectangle;
// 縮小矩形,以免繪製時出界
clientRect.Inflate(-1,-1);
// 建立漸層筆刷,從
// 左上方運行到右下角。
Brush backgroundBrush = new LinearGradientBrush(
new Point(clientRect.X,clientRect.Y),
new Point(clientRect.Width, clientRect.Height),
startColor,
endColor);
// 以漸層色填充背景....
g.FillRectangle(backgroundBrush, clientRect);
// 在客戶機地區的中間書寫文字。
g.DrawString(this.Text,
this.Font,
new SolidBrush(this.ForeColor),
clientRect,
format);
}
}

就像您所看到的,這並不是非常困難。得益於 Win Forms 和 GDI+ 物件導向的設計,無需編寫任何複雜的代碼,即可實現我們的 GradientButton,並且在設計器中,可以通過 Property Browser 操作 Text、Font、StartColor 和 EndColor。

訪問底層系統

許多架構的一個缺點就是:如果人們編寫的應用程式類型與樣本和示範中的嚴格一致,則這些架構的效果相當不錯,但有時開發人員發現,一旦他們希望用架構進行一些有創造性的工作,某些情況下就會碰到障礙或遭到失敗。如果遇到這一情況,Win Forms 架構自始至終都能夠允許開發人員訪問系統基礎結構。當然,希望 Win Forms 這樣一個設計優良的架構不會使使用者遭遇這種情況,但可能發生的情況幾乎是無限的。所有的控制項都有 Handle 屬性,允許訪問控制項的視窗控制代碼 (HWND),GDI 對象也提供了類似的控制代碼訪問過程。而且,Control 實際上擁有一個名為 WndProc 的受保護的虛擬方法,對於少數 Win Forms 尚不能支援的訊息,可以替代該方法,添加處理方式。

例如,假設您的應用程式是資源密集型的,需要響應 WM_COMPACTING。如果系統檢測到記憶體不足,會向所有高層視窗廣播 WM_COMPACTING,您就會知道 Win Forms 架構對這一訊息沒有提供內建支援,由此,可以添加如下處理過程:

/// <summary>
/// Win32Form1 的摘要說明。
/// </summary>
public class CompactableForm : System.WinForms.Form {
private EventHandler handler;
public void AddOnCompacting(EventHandler h) {
handler = (EventHandler) Delegate.Combine(handler, h);
}

protected override void OnCompacting(EventArgs e) {
// 查看運行時系統能否釋放任何東西
System.GC.Collect();
// 調用任一處理常式。
if (handler != null) handler(this, e);
}

public void RemoveOnCompacting(EventHandler h) {
handler = (EventHandler) Delegate.Remove(handler, h);
}

protected override void WndProc(ref Message m) {
case (m.msg) {
case win.WM_COMPACTING:
OnCompacting(EventArgs.Empty);
break;
}
base.WndProc(m);
}

}

只需數行代碼,當系統試著收集未用資源時,利用新的 CompactableForm 類或由此派生的類即可得到通知,並作出響應。

結論

儘管在許多開發人員的計劃中,針對 Web 的開發是當前工作的重點,而定位於熟悉的 Win32 平台仍然是一個不得不面對的情況。有了 Win Forms,Windows 開發人員無論是新手還是老手,都會發現使用豐富的介面建立複雜的應用程式是一個很方便的過程,而這些介面與 .NET Framework 中具有 Web 和資料功能的許多技術配合良好。

通過利用跨語言繼承、片段收集和安全性等通用語言運行時提高工作效率的優秀功能,開發人員將從 .NET Framework 和 Win Forms 中獲益。




相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。