天天看點

2-Windows 窗體應用程式模型

Windows 窗體的應用程式程式設計模型主要由窗體、控件及其事件組成。MDI 窗體。MDI 窗體可以在其工作區内包含名為 MDI 子窗體的其他窗體。Form 類為鍵盤處理(Tab 鍵順序)和滾動窗體的内容提供内置的支援。

 窗體

在 Windows 窗體中,Form 類是在應用程式中顯示的任何視窗的表示形式。可以使用 Form 類的 BorderStyle 屬性建立标準視窗、工具視窗、無邊框視窗和浮動視窗。還可使用 Form 類建立有模式視窗,如對話框。通過設定 Form 類的 MDIContainer 屬性,可以建立一種特殊類型的窗體 MDI 窗體。MDI 窗體可以在其工作區内包含名為 MDI 子窗體的其他窗體。Form 類為鍵盤處理(Tab 鍵順序)和滾動窗體的内容提供内置的支援。

當為應用程式設計使用者界面時,通常建立一個從 Form 派生的類。然後可以添加控件、設定屬性、建立事件處理程式以及向窗體添加程式設計邏輯。

控件

添加到窗體中的每個元件(如 Button、TextBox 或 RadioButton)稱為控件。Windows 窗體包括通常與 Windows 關聯的所有控件以及類似 Windows 窗體 DataGrid 的自定義控件。

通常可以通過設定屬性與控件進行互動,以更改其外觀和行為。例如,下面的 Form 的派生類向窗體添加一個 Button 控件,并設定該控件的 Size 和 Location。

C# source:

public class HelloWorldForm : System.Windows.Forms.Form {

    private Button button1 = new Button() ;

    private TextBox textBox1 = new TextBox();

    [STAThread]

    public static int Main(string[] args) {

        Application.Run(new HelloWorldForm());

        return 0;

    }

    public HelloWorldForm() {

        this.Text = "Hello Windows Forms World";

        this.AutoScaleBaseSize = new Size(5, 13);

        this.ClientSize = new Size(392, 117);

        this.MinimumSize = new Size(392, (117 + SystemInformation.CaptionHeight));

        this.AcceptButton=button1;

        button1.Location = new Point(256, 64);

        button1.Size = new Size(120, 40);

        button1.TabIndex = 2;

        button1.Text = "Click Me!";

        button1.Click += new System.EventHandler(button1_Click);

        textBox1.Text = "Hello Windows Forms World";

        textBox1.TabIndex = 1;

        textBox1.Size = new Size(360, 20);

        textBox1.Location = new Point(16, 24);

        this.Controls.Add(button1);

        this.Controls.Add(textBox1);

    }

}

VB source:

Public Class HelloWorldForm

    Inherits Form

    Private components As Container

    Private WithEvents button1 as Button

    Private textBox1 As New TextBox

    <STAThread()> Shared Sub Main()

        System.Windows.Forms.Application.Run(New HelloWorldForm())

    End Sub

    Public Sub New()

        MyBase.New

        Me.Text = "Hello Windows Forms World"

        Me.AutoScaleBaseSize = new Size(5, 13)

        Me.ClientSize = new Size(392, 117)

        Me.MinimumSize = new Size(392, (117 + SystemInformation.CaptionHeight))

        button1 = new Button()

        button1.Location = new Point(56, 64)

        button1.Size = new Size(90, 40)

        button1.TabIndex = 2

        button1.Text = "Click Me!"

        textBox1.Text = "Hello Windows Forms World"

        textBox1.TabIndex = 1

        textBox1.Size = new Size(360, 20)

        textBox1.Location = new Point(16, 24)

        Me.AcceptButton=button1

        Me.Controls.Add(button1)

        Me.Controls.Add(textBox1)

    End Sub

End Class

控件狀态為無模式

窗體對于何時可設定控件的屬性提供有限的限制。控件沒有阻止更新其狀态的模式。建立控件的新執行個體後,可以立即更改其狀态。例如,下面的代碼提供兩個示例,示範建立 Button 控件的有效方法。

C# source:

Button button1 = new Button();

button1.Location = new Point(256, 64);

button1.Size = new Size(120, 40);

button1.TabIndex = 1;

button1.Text = "Click Me!";

this.Controls.Add(button1);

VB source:

Dim button1 As New Button

button1.Location = New Point(256, 64)

button1.Size = New Size(120, 40)

button1.TabIndex = 1

button1.Text = "Click Me!"

Me.Controls.Add(button1)

事件

Windows 窗體程式設計模型基于事件。當控件更改狀态,如當使用者單擊按鈕時,它引發一個事件。為了處理事件,應用程式為該事件注冊一個事件處理方法。 在 Visual Basic 中,有兩種途徑可以注冊事件處理方法:

如果使用 WithEvents 關鍵字聲明控件變量,可以在方法的聲明中使用 Handles 關鍵字,将該方法注冊為事件處理方法。 可使用 AddHandler 在運作時注冊事件處理方法。

下面的代碼闡釋注冊事件處理方法的兩種途徑。

C# source:

public delegate void EventHandler(object sender, EventArgs e);

VB source:

Public Delegate Sub EventHandler(sender As object, e As EventArgs)

 Click 事件的任何事件處理方法都必須具有以下簽名。

C# source:

<access> void <name>(object sender, EventArgs evArgs)

VB source:

<access> Sub <name>(sender As object, e As EventArgs)

 對于強類型語言,如果事件處理方法的簽名與委托簽名不比對,将發生編譯時錯誤。

很多事件使用一般的 EventHandler 和 EventArgs 類。但是,一些事件要求針對所引發事件的類型的附加資訊。例如,滑鼠移動事件包括有關滑鼠指針或滑鼠按鈕位置的資訊。這些事件定義其自己的類,這些類必須從 EventHandler 和 EventArgs 類繼承。例如,MouseDown 事件使用 MouseEventHandler 和 MouseEventArgs 類。

事件命名約定

可以在特定種類的狀态更改之前和之後引發事件。在狀态更改前引發的事件通常帶有字尾“ing”。在狀态更改後引發的事件通常帶有字尾“ed”。例如,SessionEnding 事件是狀态更改前引發的,SessionEnded 事件是狀态更改後引發的。如果某狀态更改僅導緻一個事件被引發,則該事件通常沒有字尾。例如,Click 事件。

可取消的事件

根據應用程式中的情況,可能需要取消某個事件。某些事件可以取消。這些事件使用 CancelEventHandler 和 CancelEventArgs 類。CancelEventArgs 類包含名為 Cancel 的屬性。如果此屬性設定為 true,那麼當該事件處理方法傳回時,将取消該事件。通常,隻有在狀态更改前引發的事件才是可以取消的。取消事件将取消狀态更改。

用一個事件處理方法處理多個事件

如果要用一個事件處理程式處理多個事件,可通過将同一方法注冊到多個事件來實作。每個事件都必須具有相同的簽名。當對多個事件使用一個事件處理方法時,可以從 sender 參數确定哪個控件引發了事件。下面的示例闡釋處理來自兩個按鈕控件的事件的單個事件處理方法。

C# source:

....

Button button1 = new Button() ;

Button button2 = new Button() ;

....

button1.Click += new System.EventHandler(button_Click);

button2.Click += new System.EventHandler(button_Click);

....

//The event handling method

private void button_Click(object sender, EventArgs evArgs) {

    if (sender==button1) {

        MessageBox.Show("Button1 Pushed!");

    } else if (sender==button2) {

        MessageBox.Show("Button2 Pushed!");

    }

}

VB source:

....

Dim button1 As New Button

Dim button2 As New Button

....

AddHandler button1.Click, AddressOf button_Click

AddHandler button2.Click, AddressOf button_Click

....

'The event handling method

Private Sub button_Click(sender As Object, evArgs As EventArgs)

    If (sender = button1) Then

        MessageBox.Show("Button1 Pushed!")

    Else If (sender = button2) Then

        MessageBox.Show("Button2 Pushed!")

    End If

End Sub

下面的示例示範前面提到的概念。它顯示如何:

建立和顯示一個作為應用程式主入口點的窗體

向窗體添加控件

設定控件上的屬性

将事件處理方法注冊到控件

從控件擷取屬性值

在消息框中顯示文本

向關閉窗體時執行的 Dispose 方法添加代碼

VB source:

Imports System Imports System.ComponentModel

Imports System.Drawing

Imports System.Windows.Forms

Namespace Microsoft.Samples.WinForms.VB.HelloWorldForm

    Public Class HelloWorldForm

        Inherits Form

        Private components As Container

        '使用 WithEvents 聲明按鈕,以便能夠注冊聲明性事件處理程式

        Private WithEvents button1 as Button

        Private textBox1 As New TextBox

        '應用程式啟動時顯示此窗體

        <STAThread()> Shared Sub Main()

            System.Windows.Forms.Application.Run(New HelloWorldForm())

        End Sub

        Public Sub New()

            MyBase.New

            '設定窗體

            Me.Text = "Hello Windows Forms World"

            Me.AutoScaleBaseSize = new Size(5, 13)

            Me.ClientSize = new Size(392, 117)

            '将最小窗體大小設定為工作區的大小,高度與标題欄相同

            Me.MinimumSize = new Size(392, (117 + SystemInformation.CaptionHeight))

            '建立 button1

            button1 = new Button()

            button1.Location = new Point(56, 64)

            button1.Size = new Size(90, 40)

            button1.TabIndex = 2

            button1.Text = "請單擊我!"

            '建立文本框

            textBox1.Text = "Hello Windows Forms World"

            textBox1.TabIndex = 1

            textBox1.Size = new Size(360, 20)

            textBox1.Location = new Point(16, 24)

            '在窗體上設定預設按鈕

            Me.AcceptButton=button1

            '向窗體添加控件

            Me.Controls.Add(button1)

            Me.Controls.Add(textBox1)

        End Sub

        '當窗體關閉時調用

        '注意,MessageBox 調用隻是說明調用了 Dispose。

        '應使 Dispose 方法代碼盡可能地簡單可靠

        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

            Try

                MessageBox.Show("已處置!")

            Catch ex As Exception

            End Try

            MyBase.Dispose(disposing)

        End Sub

        'button2 的事件處理方法 - 使用 Handles 注冊

        Private Sub button1_Click(sender As Object, evArgs As EventArgs) Handles button1.Click

            '禁用 button1 - 我們隻想添加一個按鈕

            button1.Enabled=False

            '添加新按鈕,并使用 AddHandler 添加事件處理程式

            Dim newButton As new Button

            newButton = new Button()

            newButton.Location = new Point(256, 64)

            newButton.Size = new Size(90, 40)

            newButton.TabIndex = 4

            newButton.Text = "還請單擊我!"

            Me.Controls.Add(newButton)

            AddHandler newButton.Click, AddressOf Me.clickNewbutton

        End Sub

        '新按鈕的事件處理方法 - 使用 AddHandler 注冊

        Private Sub clickNewbutton(sender As Object, evArgs As EventArgs)

            MessageBox.Show("來自新按鈕的問候")

        End Sub

    End Class

End Namespace

C# source:

namespace Microsoft.Samples.WinForms.Cs.HelloWorldForm {

    using System;

    using System.Windows.Forms;

    using System.Drawing;

    // 不要向 Windows 窗體設計器中加載此窗體。

    // 此“快速入門”是包含控件的簡單手寫

    // 窗體的一個示例。

    public class HelloWorldForm : System.Windows.Forms.Form {

        private Button button1 = new Button() ;

        private TextBox textBox1 = new TextBox();

        //應用程式啟動時顯示此窗體

        [STAThread]

        public static int Main(string[] args) {

            Application.Run(new HelloWorldForm());

            return 0;

        }

        public HelloWorldForm() {

            //設定窗體

            this.Text = "Hello Windows Forms World";

            this.AutoScaleBaseSize = new Size(5, 13);

            this.ClientSize = new Size(392, 117);

            //将最小窗體大小設定為工作區的大小,高度與标題欄相同

            this.MinimumSize = new Size(392, (117 + SystemInformation.CaptionHeight));

            //在窗體上設定預設按鈕

            this.AcceptButton=button1;

            //建立按鈕

            button1.Location = new Point(256, 64);

            button1.Size = new Size(120, 40);

            button1.TabIndex = 2;

            button1.Text = "請單擊我!";

            //注冊事件處理程式

            button1.Click += new System.EventHandler(button1_Click);

            //建立文本框

            textBox1.Text = "Hello Windows Forms World";

            textBox1.TabIndex = 1;

            textBox1.Size = new Size(360, 20);

            textBox1.Location = new Point(16, 24);

            //向窗體添加控件

            this.Controls.Add(button1);

            this.Controls.Add(textBox1);

        }

        //當窗體關閉時調用

        //注意,MessageBox 調用隻是

        //說明調用了 Dispose。

        //應使 Dispose 方法代碼盡可能地

        //簡單可靠

        protected override void Dispose(bool disposing)

        {

            try {

                MessageBox.Show("已處置!");

            } catch(Exception) {}

            base.Dispose(disposing);

        }

        //事件處理方法

        private void button1_Click(object sender, EventArgs evArgs) {

            MessageBox.Show("文本是:'" + textBox1.Text + "'");

        }

    }

}

繼續閱讀