利用單一事件處理程序(Event Handler)來減少程式碼及提高...生產力吧


Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
'Code...
End Sub


  以上就是今天的主角「Event Handler」,Event Handler簡單說,就是將物件事件與事件處理程序做關連,以上例來說,我們的物件是「Button1」,物件事件是「Button1.Click」(最後的地方),事件處理程序是「Button1_Click()」。其中的重點其實在「Handles」身上,Handles
,注意看這個單子,有加「s」哦,也就是說,這個Event Handler本身不只可以處理單一個事件,也可以同事處理多個物件的事件。

  我舉個簡單的例子,我們在寫資料庫程式時,Select自為一組,Insert、Update、Delete這三個通常也自成一組,但我們一般的寫法就是:


'Insert Button
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
'Insert Code...
End Sub

'Update Button
Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
'Update Code...
End Sub

'Delete Button
Protected Sub Button3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button3.Click
'Delete Code...
End Sub


  看起來沒什麼問題,執行起來也會很順暢。但其實這三個功能的程式,我們常常是寫在一起的,很少寫了Insert確不寫Update和Delete程式碼,所以我們接下來要簡化程式碼而且還可以集中管理的方便性。

  第一件事,我們要使三個Button都使用同一個Event Handler,所以我們將上面三段合成一段:


Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
'Code...
End Sub


  注意最後「Handles Button1.Click, Button2.Click, Button3.Click」,將三個Button物件Click事件與Button1_Click做關連,也就是說Button1, Button2, Button3的Click都交給Button1_Click處理常式來處理。這樣設定之後,接下來的問題只有一個,就是說,我們要如何分辨「我是誰?Who am i?」

  因為現在三個Button都關連同一事件處理程序,如不能分辦是「誰」,那程式怎麼知道我們要處理Button1的Click程式碼還是Button2或Button3的Click程式碼?這個Who am i的遊戲解法有二。

方法一:使用Button的Command事件



  在你將Button物件拉進ASP.NET網頁後,請在屬性視窗找一個「CommandName」的屬性,這個屬性能讓我們為Button物件進行命令關聯,我們進行以下設定:

  Button1 → CommandName → 新增
  Button2 → CommandName → 修改
  Button3 → CommandName → 刪除

  經過CommandName的設定後,我們就能在Button1_Click進行以下的處理:


Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
  'CommandName Sample Code...
  'CType將sender轉換型別為Button,然後取得CommandName的值來比較
If CType(sender, Button).CommandName = "新增" Then
'Insert Code
ElseIf CType(sender, Button).CommandName = "修改" Then
'Update Code
ElseIf CType(sender, Button).CommandName = "刪除" Then
'Delete Code
End If
End Sub


  這樣的程式碼有沒有比每一個Button單獨一個事件處理程序來的好。但這樣的步驟還是太麻煩,因為還需要先設定每一Button的CommandName,然後在程式中還再透過CType()來轉換型別後才能取得CommandName的值。其實還有更快更簡便的方法,就是直接使用Sender.Text屬性。

方法二:使用Sender.Text加Select Case

  *不用設定CommandName


Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
  'Sender.Text Sample Code...
  'Sender.Text取得傳入Button物件的Text屬性值
Select Case sender.text
Case "新增"
'Insert Code
Case "修改"
'Update Code
Case "刪除"
'Delete Code
End Select
End Sub


  程式碼就這樣,沒了,簡單吧!我們直接對sender.text做Select Case動作,而sender.text是直接取得Button(1-3).Text的屬性值。這樣的程式碼連CommandName都不用設定,而是直接判斷Button(1-3).Text的屬性值,然後依Button(1-3).Text的不同撰寫處理程式。

  由以上範例我們可以看出,一是透過簡單共用事件處理程序,我們就可以減少不少的程式碼,二是集中管理相同目標、目的的程式碼。

範例:MultiView使用單一事件管理程序來切換View


  我們先在畫面上拉一個MultiView控制項,然後在MultiView控制項裡拉三個View控制項,三個View控制項裡各打上一些文字,

  MultiView
    → View1 → "This is View 1"
    → View2 → "This is View 2"
    → View3 → "This is View 3"

  然後在MultiView下方拉三個LinkButton控制項,LinkButton文字設定為View1、View2、View3,

  LinkButton1.Text = View1
  LinkButton2.Text = View2
  LinkButton3.Text = View3

  我們利用這三個LinkButton來切換MultiView裡的View。原始方法就是在每一個LinkButton的Click事件中寫程式。但我們既然學了好用的單一事件處理程序,讓我們來試試看:


Protected Sub lb1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lb1.Click, lb2.Click, lb2.Click
'mv代表MultiView、lb代表LinkButton
'ActiveViewIndex用來設定所要顯示的View控制項,0代表第一個View…
Select Case sender.text
Case "View1"
mv.ActiveViewIndex = 0
Case "View2"
mv.ActiveViewIndex = 1
Case "View3"
mv.ActiveViewIndex = 2
End Select
End Sub


  這樣的Code看起來是不是很舒服,我們把有相同目的、相同目標的程式碼集中起來,也減少了許多頁面裡的Code,這樣不僅僅是對Coding人員有好處,對執行效率也會能有所提升。想想,如果一個大專案裡,共有100萬行程式碼,如果透這像這樣的小技巧,減為95萬行好了,能減少5%的程式確能執行一樣的效果。

  如果沒有感覺,一樣的工作1000萬行減為950萬行,你如果可以化身為Server,請選擇?

  ps. Windows 95作業系統有高達一千一百萬行程式。

4 則留言:

  1. 你好,請問C#要如何達到相同方式

    回覆刪除
  2. 方法一CommandName 或方法二 sender都可以呀,差異只有語法的不同,Try it, 如果寫不出來,Post your code in there.

    回覆刪除
  3. 問題如一樓,請問C#要如何達到相同方式
    我都找步道相關介紹

    回覆刪除
  4. Code變得乾淨,心情也舒服許多!!
    非常感謝KKBruce老師分享!!讓我學到Clean Code的一些方法

    另外樓上的兩位仁兄 若是像我一樣剛接觸.NET不久(個人用VB.NET語法)
    語法上不熟悉可以找網路上一些C#轉VB.NET 或 VB.NET轉C#的工具 (例如:http://converter.telerik.com/)
    在進行文章的練習

    回覆刪除

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「+1」,我會很高興的。

无觅相关文章插件,迅速提升网站流量