01 十一月, 2009 10:54
終於,我們要真正開始寫程式了。
這一篇分上下兩集,要介紹的是如何實作 Form 的繼承物件,這是在 2006 年
發表在自己的 Blog 上面的,原文請參考:
http://jamesjantw.blogspot.com/2006/09/net-windows-form.html
茲節錄部分文字,以作為說明
緣起:
之前在 VB6 的時代,常常會撰寫一些排程的程式去執行一些 Backend 的作業(當然你也可以用 OS 的 Schedule 來排程)。每次需要新的作業時都是將程式目錄 Copy 一遍再逐一去改命名,雖然自己已經有一些開發的 Pattern(ini 檔、log 檔、Error 發送 email 通知開發者),開發速度上也很快,但是如果我要讓所有的程式都增加一個新的功能,這樣我得為每一個專案加入這個功能,為數眾多時這可是頗耗時間的。
以前開發 Delphi (3.0) 時,就已經有 Form 繼承的作法了,程式模組可以重複使用,那為什麼同性質的 Form 不可以呢?基於這樣的需求,所以決定第一支程式以 Windows Form 繼承實作做為開端。
思考:
1.哪些功能該擺在 BaseForm 上?Inheritance consideration
2.如何擴充已有的功能?Overrides
3.如何讓同一功能具備多樣性?Overloads
4.應用程式設定檔
5.應用程式記錄檔
6.Exception Notification(通知錯誤訊息 & 出錯行號)
好吧,我們就來試做看看!
首先,開啟一個 Visual Studio 專案,選擇「類別庫」(Class Library)(程式當時是使用 .Net 2.0 的環境,抓圖片時沒有變更。)
Project
我們使用到三個類別,如下圖所示:(當然這是完成圖)
CLass Diagram

接下來,先拉好一個 Form,將我們要的元件擺上去。
這個程式是用來作自動執行小程式的範本,我現在有需要排程做運算的程式,都使用他作為
Parent Form 來繼承,我只要將要執行的程式碼加上去,就變成一個新程式了,一些
Error Handling 啦,Log 啦都自動有了,我也不用去另外設計 Form。
BaseForm
底下是程式碼的內容,我們在 Base Form Class 上,又宣告了兩個物件,Log 跟 Send Mail
他們主要是用來作 Error Handling 與錯誤通知用的。
BaseForm.vb
- Public Class BaseForm
- Protected RunTimer As Integer
- Protected sendmail As SendMail
- Protected log As Log
- Private Sub BaseForm_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
- mnuSwitch.Text = "離開"
- mnuSwitch_Click(sender, e)
- End Sub
- Private Sub BaseForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
- sendmail = New SendMail()
- log = New Log()
- Timer1.Enabled = True
- ShowTimer()
- End Sub
- Private Sub ShowTimer()
- ToolStripStatusLabel2.Text = Now().ToString
- End Sub
- Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
- ShowTimer()
- End Sub
- Private Sub mnuSwitch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuSwitch.Click
- Timer2.Enabled = mnuSwitch.Text.Equals("啟動")
- ListBox1.Items.Add(Now().ToString & " " & mnuSwitch.Text)
- log.Writeln(mnuSwitch.Text, TraceEventType.Information)
- mnuSwitch.Text = IIf(mnuSwitch.Text.Equals("啟動"), "停止", "啟動")
- End Sub
- Protected Sub ExceptionHandler(ByVal ex As Exception, ByVal ErrorMessage As String)
- My.Application.Log.WriteException(ex, _
- TraceEventType.Error, _
- Now().ToString)
- sendmail.Message.Subject = ErrorMessage
- sendmail.Message.Body = "Message ---" & vbCrLf & ex.Message & vbCrLf & vbCrLf & _
- "Source ---" & vbCrLf & ex.Source & vbCrLf & vbCrLf & _
- "StackTrace ---" & vbCrLf & ex.StackTrace & vbCrLf & vbCrLf & _
- "TargetSite ---" & vbCrLf & ex.TargetSite.ToString()
- sendmail.Send()
- End Sub
- End Class
他會將錯誤寫到 Log File(相關設定下篇再說明)以及發送 mail 通知。
如果您眼尖一點,可以發現,SendMail 並沒有指定 Form、To以及 SMTP Host!這是因為在 Base Form 上不應該指定這些,因為那是給實際執行的程式去設定的!所以在繼承的程式中,要去指定這幾個屬性。
Log.vb
- Public Class Log
- Public Sub New()
- End Sub
- Public Sub Writeln(ByVal strLog As String, ByVal TraceEvent As Integer)
- Try
- Application.DoEvents()
- My.Application.Log.WriteEntry(strLog & vbTab & Now().ToString, TraceEvent)
- Catch ex As IO.IOException
- My.Application.Log.WriteException(ex, _
- TraceEventType.Error, _
- Now().ToString)
- End Try
- End Sub
- End Class
SendMail.vb
- Imports System.Net.Mail.SmtpClient
- Imports System.Net.Mail.MailMessage
- Public Class SendMail
- Public Message As System.Net.Mail.MailMessage
推文( 1 )



