2012年11月1日 星期四

C#.NET 程式碼中對多個控制項指定單一事件處理程序

在 aspx 檔案中,不直接針對「控制項」指定「事件處理程序」,而是在 aspx.cs 檔案中透過程式碼去指定。

我們在介面中設計三個按鈕,其 ID 及 Text 屬性為 Button1~Button3 ,並且提供了三個 Label 供我們顯示測試的輸出結果。

<test.aspx>
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs" Inherits="test" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="Button1" runat="server" Text="Button1" />
        <asp:Button ID="Button2" runat="server" Text="Button2" />
        <asp:Button ID="Button3" runat="server" Text="Button3" />
        <br />
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
        <br />
        <asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
    </div>
    </form>
</body>
</html>

<test.aspx.cs>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class test : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Button1.Click += new EventHandler(Button_Click1);
        Button2.Click += new EventHandler(Button_Click1);
        Button3.Click += new EventHandler(Button_Click1);
    }

    protected void Button_Click1(object sender, EventArgs e)
    {
        Label1.Text = "觸發 Button_Click1 事件處理程序 ((Button)sender).ID = " + ((Button)sender).ID;
        Label2.Text = "";
    }
}


test.aspx 畫面:






此範例中:
Button1 ~ Button3 代表物件
Button1.Click ~ Button3.Click 代表該物件的事件(也就是 Button 的 Click 事件)
Button_Click1 及 Button_Click2 代表事件處理程序

從程式碼中可以看得出來,我在 test.aspx 檔案中並未針對 asp:Button 標籤指定任何事件處理程序的動作(一般來其標籤會有 OnClick="Button1_Click" 類似這樣的屬性)

而是在 test.aspx 檔案的後置程式碼 (Code Behind) 的檔案中(text.aspx.cs)對 Button1~Button3 的 Click 屬性中去指定事件處理程序

Button1.Click += new EventHandler(Button_Click1);
Button2.Click += new EventHandler(Button_Click1);
Button3.Click += new EventHandler(Button_Click1);

new EventHandler 產生一個新的 EventHandler(事件處理程序)型別物件,建構子傳入參數 Button_Click1,以上動作也就是產生一個「指定事件處理程序為 Button_Click1 這個方法」的物件。

然後再將此 EventHandler 型態的物件透過「+= 」運算子放到指定物件(Button1~Button3)的 Click 事件屬性裡面。

這樣就可以讓 Button1 ~ Button3 的事件都統一透過 Button_Click1 這個方法去執行,呼應我們文章主題寫的,對多個控制項指定單一事件處理程序。

然後最後是我們真正工作的事件處理程序(Button_Click1 方法)

    protected void Button_Click1(object sender, EventArgs e)
    {
        Label1.Text = "觸發 Button_Click1 事件處理程序 ((Button)sender).ID = " + ((Button)sender).ID;
        Label2.Text = "";
    }

以此範例中,當按鈕按下時會觸發事件處理程序 Button_Click1,會傳入兩個參數,一個是 object 型態的物件  sender,另一個是 EventArgs 型態的物件 e

而我們可以透過傳入的 sender 來判斷觸發事件的是哪個物件

由於傳入的  sender 是 object 型態的物件,我們將其強制型別轉換成 Button 型態,才可以順利取得該物件的 ID,也就是判斷您按下的按鈕是哪一顆。

執行畫面:







至於為何要使用「+= 」而不是「=」呢?這是因為一個物件事件,可以觸發多個事件處理程序,我們加入以下程式碼

Button3.Click += new EventHandler(Button_Click2);

這樣子對 Button3 來說,當 Click 事件發生時,除了會觸發 Button_Click1 之外,還會觸發 Button_Click2 事件處理程序

執行畫面:






以下附上加入 Button_Click2 後的完整的程式碼可以自己執行看看比較清楚^^
一開始接觸時也是很多疑惑,試著將自己的學習過程記錄下來,有問題歡迎各位留言討論。

<test.aspx.cs>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class test : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Button1.Click += new EventHandler(Button_Click1);
        Button2.Click += new EventHandler(Button_Click1);
        Button3.Click += new EventHandler(Button_Click1);

        Button3.Click += new EventHandler(Button_Click2);
    }

    protected void Button_Click1(object sender, EventArgs e)
    {
        Label1.Text = "觸發 Button_Click1 事件處理程序 ((Button)sender).ID = " + ((Button)sender).ID;
        Label2.Text = "";
    }

    protected void Button_Click2(object sender, EventArgs e)
    {
        Label2.Text = "觸發 Button_Click2 事件處理程序,((Button)sender).ID = " + ((Button)sender).ID;
    }
}

沒有留言:

張貼留言