VB.NET AddressOf 筆記 (進階篇)
在 VB.NET 中,AddressOfAddressOf 就像是一個智慧型的電話通訊錄,它不只記錄了聯絡人的電話號碼,還能夠自動撥號。當需要將某個方法或函數的「通話權限」交給其他程式碼時,AddressOf 就能建立這個連接,讓其他程式碼能夠在適當的時機呼叫該方法。是一個實用的關鍵字。它可以讓方法變成變數來使用。平常撰寫程式都是直接呼叫方法,像是 Calculate(),但有了 AddressOf,可以把這個方法「打包」起來,存到一個變數裡,需要的時候再拿出來執行。
為什麼需要這樣做呢?最常見的情況是:程式需要根據不同的條件,執行不同的方法。例如使用者選擇「加法」就執行加法方法,選擇「減法」就執行減法方法。如果沒有 AddressOf,可能需要寫一大堆 If...Then 或 Select Case。但有了 AddressOf,可以直接把對應的方法存到變數裡,程式碼會變得乾淨很多。
認識 AddressOf
AddressOf 是什麼? 簡單來說,AddressOf 是一個讓方法變成變數的關鍵字。平常撰寫程式都是直接呼叫方法,像 DoSomething()。但有時候希望能夠「選擇」要執行哪個方法,這時候就可以用 AddressOf 把方法先「存起來」,等需要的時候再拿出來執行。
- AddressOf 的角色: 它將方法的位址轉換為委派,讓方法可以像變數一樣被傳遞和呼叫。
AddressOf 的核心優勢
- 把方法變成變數就像可以把數字存在變數裡一樣,AddressOf 讓方法也能存在變數裡。這樣就可以在程式執行的過程中,隨時決定要用哪個方法,而不用寫一堆 If...Then 來選擇。:可以把方法存在變數裡,需要的時候再拿出來執行。
- 自動檢查格式就像不能把文字存到數字變數裡一樣,AddressOf 也會檢查方法格式是否正確。如果參數或回傳值不對,程式編譯時就會提醒,避免執行時出錯。:程式會自動檢查方法的參數和回傳值是否正確,避免出錯。
- 方便傳遞方法就像可以把數字傳給其他程式一樣,也可以把方法傳給其他程式使用。例如可以把「處理資料的方法」傳給「讀取檔案的程式」,讓它在讀完檔案後自動處理資料。:可以把方法當作參數傳給其他程式使用。
- 隨時換方法就像可以隨時換掉變數裡的數字一樣,也可以隨時換掉變數裡的方法。這樣程式就可以根據不同的情況,執行不同的處理方式,非常靈活。:程式執行時可以隨時更換要執行的方法,超級靈活。
AddressOf 的三種核心類型
根據需求的不同,AddressOf 的實作方式可以從極簡到複雜,以下是三種核心的應用場景整理。
類型一:基本委派 (Basic Delegate)
當需要將方法作為變數使用,但不需複雜邏輯時,可以使用最簡潔的「基本委派」。這就像直接將方法位址傳遞給變數。
基本語法
Public Delegate Function MathOperation(a As Integer, b As Integer) As Integer
Private currentOperation As MathOperation = AddressOf AddNumbers
使用的控制項:
- TextBox1:輸入第一個數字。
- TextBox2:輸入第二個數字。
- ComboBox1:選擇運算方式。
- Button1:執行計算。
- Label1:顯示計算結果。
範例程式碼
' 定義一個委派格式:接受兩個整數,回傳一個整數
Public Delegate Function MathOperation(a As Integer, b As Integer) As Integer
' 用 AddressOf 的寫法:把方法當變數用
Private currentOperation As MathOperation ' 這個變數可以存放任何符合格式的方法
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
' 根據使用者選擇,把對應的方法存到變數裡
Select Case ComboBox1.SelectedIndex
Case 0 ' 加法
currentOperation = AddressOf AddNumbers ' 把加法方法存起來
Case 1 ' 減法
currentOperation = AddressOf SubtractNumbers ' 把減法方法存起來
Case 2 ' 乘法
currentOperation = AddressOf MultiplyNumbers ' 把乘法方法存起來
End Select
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim num1 As Integer = Integer.Parse(TextBox1.Text)
Dim num2 As Integer = Integer.Parse(TextBox2.Text)
' 直接執行之前存起來的方法,不用任何條件判斷!
Dim result As Integer = currentOperation(num1, num2)
Label1.Text = "結果:" & result.ToString()
End Sub
' 各種計算方法
Private Function AddNumbers(a As Integer, b As Integer) As Integer
Return a + b
End Function
Private Function SubtractNumbers(a As Integer, b As Integer) As Integer
Return a - b
End Function
Private Function MultiplyNumbers(a As Integer, b As Integer) As Integer
Return a * b
End Function
限制與迴避方法
限制:基本委派最大的限制是無法加入任何驗證或加工邏輯。所有方法都會被直接接受。
迴避方法:如果需要對方法進行檢查或加工,則必須改用下面介紹的「多重委派」或「非同步委派」。
類型二:多重委派 (Multicast Delegate) - 多個方法鏈結
這是委派最常見的進階功能,可以同時執行多個方法。這就像將多個方法鏈結起來,一次呼叫全部執行。
基本語法
Public Delegate Sub NotificationHandler(message As String)
Private allHandlers As NotificationHandler
allHandlers = AddressOf EmailNotification
allHandlers = [Delegate].Combine(allHandlers, AddressOf SmsNotification)
範例程式碼
Public Class MulticastDelegateDemo
Public Delegate Sub NotificationHandler(message As String)
Private allHandlers As NotificationHandler
Private isHandlersRegistered As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' 初始化介面
TextBox1.PlaceholderText = "請輸入要發送的通知訊息"
Label1.Text = "註冊狀態:未註冊處理器"
Label2.Text = "狀態:準備就緒"
ListBox1.Items.Clear()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' 發送通知
Dim message As String = TextBox1.Text.Trim()
If String.IsNullOrEmpty(message) Then
Label2.Text = "狀態:錯誤 - 請輸入通知訊息"
Return
End If
If Not isHandlersRegistered Then
Label2.Text = "狀態:錯誤 - 請先註冊處理器"
Return
End If
Label2.Text = "狀態:發送通知中..."
SendNotification(message)
Label2.Text = "狀態:通知發送完成"
' 清空輸入框
TextBox1.Clear()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
' 註冊所有處理器
If Not isHandlersRegistered Then
RegisterMultipleHandlers()
Label1.Text = "註冊狀態:已註冊多個處理器"
Label2.Text = "狀態:處理器註冊完成"
Else
Label2.Text = "狀態:處理器已經註冊過了"
End If
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
' 清除所有處理器
If isHandlersRegistered Then
ClearAllHandlers()
Label1.Text = "註冊狀態:未註冊處理器"
Label2.Text = "狀態:已清除所有處理器"
Else
Label2.Text = "狀態:沒有處理器需要清除"
End If
End Sub
Private Sub RegisterMultipleHandlers()
' 使用 AddressOf 註冊多個處理器
allHandlers = AddressOf EmailNotification
allHandlers = [Delegate].Combine(allHandlers, AddressOf SmsNotification)
allHandlers = [Delegate].Combine(allHandlers, AddressOf LogNotification)
isHandlersRegistered = True
End Sub
Private Sub ClearAllHandlers()
' 清除所有處理器
allHandlers = Nothing
isHandlersRegistered = False
End Sub
Private Sub EmailNotification(message As String)
' 模擬發送電子郵件通知
ListBox1.Items.Add($"[Email] {DateTime.Now:HH:mm:ss} - {message}")
End Sub
Private Sub SmsNotification(message As String)
' 模擬發送簡訊通知
ListBox1.Items.Add($"[SMS] {DateTime.Now:HH:mm:ss} - {message}")
End Sub
Private Sub LogNotification(message As String)
' 模擬記錄日誌
ListBox1.Items.Add($"[Log] {DateTime.Now:HH:mm:ss} - 系統記錄:{message}")
End Sub
Private Sub SendNotification(message As String)
' 透過多重委派同時執行所有通知方法
If allHandlers IsNot Nothing Then
allHandlers.Invoke(message)
' 自動捲動到最新項目
If ListBox1.Items.Count > 0 Then
ListBox1.TopIndex = ListBox1.Items.Count - 1
End If
End If
End Sub
End Class
使用的控制項:
- TextBox1:輸入通知訊息。
- Button1:發送通知。
- Button2:註冊所有處理器。
- Button3:清除所有處理器。
- ListBox1:顯示通知記錄。
- Label1:顯示註冊狀態。
- Label2:顯示操作狀態。
限制與迴避方法
限制:多重委派需要手動管理方法鏈結,程式碼會比基本委派稍長。
迴避方法:為了獲得多方法執行,額外的管理是必要的。重點在於區分何時需要多重,何時不需要,以選擇最適合的委派類型。
類型三:事件處理委派 (Event Handling Delegate) - 動態綁定
委派常用於事件處理,可以動態綁定方法。這就像將方法綁定到事件,事件觸發時自動執行。
基本語法
Public Event MyEvent As EventHandler
AddHandler MyEvent, AddressOf MyMethod
範例程式碼
Public Class EventHandlingDemo
' 定義事件
Public Event DataProcessed(sender As Object, e As EventArgs)
Private Sub ProcessData()
' 處理資料邏輯...
RaiseEvent DataProcessed(Me, EventArgs.Empty)
End Sub
' 事件處理方法
Private Sub OnDataProcessed(sender As Object, e As EventArgs)
Label1.Text = "資料已處理完成"
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' 使用 AddressOf 綁定事件處理器
AddHandler DataProcessed, AddressOf OnDataProcessed
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ProcessData()
End Sub
End Class
使用的控制項:
- Button1:觸發資料處理。
- Label1:顯示處理狀態。
限制與迴避方法
限制:事件處理委派無法直接修改事件來源。任何嘗試直接修改的程式碼都會導致編譯錯誤。
迴避方法:這是其設計目的,用來確保事件完整性。如果需要修改,只能去改變它所依賴的來源方法。
AddressOf 類型比較表
| 委派類型 | 優點 | 適用場景與限制 |
|---|---|---|
|
基本委派 單一方法基本委派適合簡單的單一方法傳遞。 |
簡單易用 高效能 | 不支援多方法 |
|
多重委派 多方法鏈結多重委派適合需要同時執行多個方法的場景。 |
可同時執行多方法 靈活 | 管理複雜 |
|
事件處理委派 動態綁定事件處理委派適合事件驅動程式設計。 |
解耦合 易擴充 | 需手動綁定 |
AddressOf vs. 其他方法
AddressOf 與 Lambda、Action/Func 的比較。
| 方法 | 優點 | 缺點 |
|---|---|---|
|
AddressOf 委派方法AddressOf 就像是為既有的電話號碼製作通訊錄條目,它可以指向任何已經存在的方法,讓這些方法能夠透過委派的方式被呼叫。這種方式特別適合將現有的方法整合到委派系統中,保持程式碼的整潔和模組化。 |
程式編譯時會檢查格式,安全性高 執行效能佳,接近直接呼叫方法 可重複使用現有方法 支援靜態方法和物件方法 | 需要預先定義方法 寫法相對較長 不支援內嵌程式邏輯 |
|
Lambda 表達式 匿名程式Lambda 表達式就像是可以即時撰寫和使用的便條紙,當需要簡單的邏輯處理時,可以直接在需要的地方寫下處理方式,而不需要事先準備專門的方法。這種方式讓程式碼更加簡潔,特別適合一次性使用的簡單邏輯。 |
語法簡潔,可內嵌定義 支援閉包,可存取外部變數 適合簡單的邏輯處理 LINQ 查詢中廣泛使用 | 可讀性可能較差 除錯相對困難 過度使用會影響程式碼結構 |
|
Action/Func 內建委派Action 和 Func 就像是標準化的通訊協定,Action 用於不需要回傳值的通話,Func 用於需要回傳值的通話。這些標準化的委派型別讓程式碼更加統一和可互操作,不需要為每種情況都定義專門的委派型別。 |
內建通用委派,無需自訂 標準化,提高程式碼一致性 支援最多 16 個參數 與 .NET 框架高度整合 | 參數過多時宣告冗長 缺乏有意義的委派名稱 不支援 ByRef 參數 |
進階 AddressOf 技巧
技巧一:委派事件通知
使用 AddressOf 結合事件通知,讓方法改變時自動更新。
範例程式碼
Imports System.ComponentModel
Public Class ViewModel
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Delegate Function MathOperation(a As Integer, b As Integer) As Integer
Private _currentOperation As MathOperation
Public Property CurrentOperation As MathOperation
Get
Return _currentOperation
End Get
Set(value As MathOperation)
If _currentOperation IsNot value Then
_currentOperation = value
OnPropertyChanged(NameOf(CurrentOperation))
End If
End Set
End Property
Protected Sub OnPropertyChanged(propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
技巧二:非同步委派
使用 AddressOf 實現非同步呼叫。
範例程式碼
Public Delegate Function LongRunningOperation() As String
Private Sub StartAsyncOperation()
Dim operation As LongRunningOperation = AddressOf PerformLongTask
operation.BeginInvoke(AddressOf OnOperationCompleted, Nothing)
End Sub
Private Function PerformLongTask() As String
' 模擬長時間操作
Thread.Sleep(2000)
Return "操作完成"
End Function
Private Sub OnOperationCompleted(ar As IAsyncResult)
Dim operation As LongRunningOperation = CType(ar.AsyncState, LongRunningOperation)
Dim result As String = operation.EndInvoke(ar)
' 更新 UI
End Sub
技巧三:泛型委派
使用 AddressOf 與泛型委派。
範例程式碼
Public Delegate Function Converter(Of TInput, TOutput)(input As TInput) As TOutput
Private Sub UseGenericDelegate()
Dim converter As Converter(Of String, Integer) = AddressOf StringToInt
Dim result As Integer = converter("123")
End Sub
Private Function StringToInt(input As String) As Integer
Return Integer.Parse(input)
End Function
AddressOf 最佳實務建議
建議一:優先選擇 AddressOf
除非需要內嵌邏輯,否則都應該優先使用 AddressOf。它不僅更安全,也更易維護。
建議二:適當使用委派命名慣例
委派名稱應該描述其目的,並遵循 PascalCase。例如:MathOperation、NotificationHandler。
建議三:謹慎處理委派中的例外
在委派呼叫中拋出例外應該謹慎,因為它可能影響呼叫鏈。
注意事項:避免在委派中執行耗時操作
委派不應該執行耗時的操作,如檔案 I/O。這些操作更適合放在專門方法中。
綜合實戰範例
以下是一個綜合運用各種 AddressOf 技巧的完整範例,展示如何建立一個檔案處理系統。
範例:檔案處理系統
Imports System.IO
Imports System.Text
Public Class FileProcessorForm
' 定義檔案處理委派格式
Public Delegate Function FileOperationDelegate(filePath As String, Optional parameter As String = "") As String
' 儲存目前選擇的檔案操作方法
Private currentFileOperation As FileOperationDelegate
' 儲存操作記錄
Private operationLog As New List(Of String)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' 初始化介面
SetupFileOperations()
' 設定預設操作為讀取檔案
ComboBox1.SelectedIndex = 0
UpdateCurrentOperation()
' 初始化其他控制項
Label1.Text = "狀態:等待操作"
Label2.Text = "目前操作:讀取檔案"
TextBox3.Multiline = True
TextBox3.ScrollBars = ScrollBars.Vertical
TextBox3.ReadOnly = True
TextBox3.Text = "操作結果會顯示在這裡..."
End Sub
Private Sub SetupFileOperations()
' 設定檔案操作選項
ComboBox1.Items.Clear()
ComboBox1.Items.Add("讀取檔案")
ComboBox1.Items.Add("寫入檔案")
ComboBox1.Items.Add("複製檔案")
ComboBox1.Items.Add("刪除檔案")
ComboBox1.Items.Add("檔案資訊")
ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
' 設定提示文字
TextBox1.PlaceholderText = "請輸入檔案路徑"
TextBox2.PlaceholderText = "請輸入相關參數"
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
' 當使用者選擇不同操作時,更新委派
UpdateCurrentOperation()
UpdateInterfaceForOperation()
End Sub
Private Sub UpdateCurrentOperation()
' 根據使用者選擇,使用 AddressOf 設定對應的檔案操作方法
Select Case ComboBox1.SelectedIndex
Case 0 ' 讀取檔案
currentFileOperation = AddressOf ReadFileContent
Label2.Text = "目前操作:讀取檔案"
Case 1 ' 寫入檔案
currentFileOperation = AddressOf WriteFileContent
Label2.Text = "目前操作:寫入檔案"
Case 2 ' 複製檔案
currentFileOperation = AddressOf CopyFileToDestination
Label2.Text = "目前操作:複製檔案"
Case 3 ' 刪除檔案
currentFileOperation = AddressOf DeleteFileOperation
Label2.Text = "目前操作:刪除檔案"
Case 4 ' 檔案資訊
currentFileOperation = AddressOf GetFileInformation
Label2.Text = "目前操作:檔案資訊"
End Select
End Sub
Private Sub UpdateInterfaceForOperation()
' 根據選擇的操作更新介面提示
Select Case ComboBox1.SelectedIndex
Case 0 ' 讀取檔案
TextBox2.PlaceholderText = "(不需要參數)"
TextBox2.Enabled = False
Case 1 ' 寫入檔案
TextBox2.PlaceholderText = "請輸入要寫入的內容"
TextBox2.Enabled = True
Case 2 ' 複製檔案
TextBox2.PlaceholderText = "請輸入目標路徑"
TextBox2.Enabled = True
Case 3 ' 刪除檔案
TextBox2.PlaceholderText = "(不需要參數)"
TextBox2.Enabled = False
Case 4 ' 檔案資訊
TextBox2.PlaceholderText = "(不需要參數)"
TextBox2.Enabled = False
End Select
End Sub
' 各種檔案操作方法的實作
Private Function ReadFileContent(filePath As String, Optional parameter As String = "") As String
Try
If Not File.Exists(filePath) Then
Return "錯誤:檔案不存在"
End If
Dim content As String = File.ReadAllText(filePath, Encoding.UTF8)
Return $"檔案讀取成功!{vbCrLf}檔案大小:{content.Length} 個字元{vbCrLf}檔案內容:{vbCrLf}{content}"
Catch ex As Exception
Return $"讀取檔案時發生錯誤:{ex.Message}"
End Try
End Function
Private Function WriteFileContent(filePath As String, Optional parameter As String = "") As String
Try
If String.IsNullOrEmpty(parameter) Then
Return "錯誤:未提供要寫入的內容"
End If
File.WriteAllText(filePath, parameter, Encoding.UTF8)
Return $"檔案寫入成功!{vbCrLf}寫入位置:{filePath}{vbCrLf}寫入內容長度:{parameter.Length} 個字元"
Catch ex As Exception
Return $"寫入檔案時發生錯誤:{ex.Message}"
End Try
End Function
Private Function CopyFileToDestination(filePath As String, Optional parameter As String = "") As String
Try
If Not File.Exists(filePath) Then
Return "錯誤:來源檔案不存在"
End If
If String.IsNullOrEmpty(parameter) Then
Return "錯誤:未提供目標路徑"
End If
File.Copy(filePath, parameter, True)
Dim fileInfo As New FileInfo(filePath)
Return $"檔案複製成功!{vbCrLf}來源:{filePath}{vbCrLf}目標:{parameter}{vbCrLf}檔案大小:{fileInfo.Length} 位元組"
Catch ex As Exception
Return $"複製檔案時發生錯誤:{ex.Message}"
End Try
End Function
Private Function DeleteFileOperation(filePath As String, Optional parameter As String = "") As String
Try
If Not File.Exists(filePath) Then
Return "錯誤:檔案不存在"
End If
Dim fileInfo As New FileInfo(filePath)
Dim fileName As String = fileInfo.Name
Dim fileSize As Long = fileInfo.Length
File.Delete(filePath)
Return $"檔案刪除成功!{vbCrLf}已刪除檔案:{fileName}{vbCrLf}檔案大小:{fileSize} 位元組{vbCrLf}原路徑:{filePath}"
Catch ex As Exception
Return $"刪除檔案時發生錯誤:{ex.Message}"
End Try
End Function
Private Function GetFileInformation(filePath As String, Optional parameter As String = "") As String
Try
If Not File.Exists(filePath) Then
Return "錯誤:檔案不存在"
End If
Dim fileInfo As New FileInfo(filePath)
Dim info As New StringBuilder()
info.AppendLine("檔案資訊詳細內容:")
info.AppendLine($"檔案名稱:{fileInfo.Name}")
info.AppendLine($"完整路徑:{fileInfo.FullName}")
info.AppendLine($"檔案大小:{fileInfo.Length:N0} 位元組")
info.AppendLine($"建立時間:{fileInfo.CreationTime:yyyy-MM-dd HH:mm:ss}")
info.AppendLine($"修改時間:{fileInfo.LastWriteTime:yyyy-MM-dd HH:mm:ss}")
info.AppendLine($"存取時間:{fileInfo.LastAccessTime:yyyy-MM-dd HH:mm:ss}")
info.AppendLine($"唯讀屬性:{If(fileInfo.IsReadOnly, "是", "否")}")
info.AppendLine($"副檔名:{fileInfo.Extension}")
info.AppendLine($"目錄位置:{fileInfo.DirectoryName}")
Return info.ToString()
Catch ex As Exception
Return $"取得檔案資訊時發生錯誤:{ex.Message}"
End Try
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
' 取得使用者輸入
Dim filePath As String = TextBox1.Text.Trim()
Dim parameter As String = TextBox2.Text.Trim()
' 驗證輸入
If String.IsNullOrEmpty(filePath) Then
Label1.Text = "狀態:錯誤 - 請輸入檔案路徑"
TextBox3.Text = "錯誤:檔案路徑不能為空白"
Return
End If
' 檢查委派是否已設定
If currentFileOperation Is Nothing Then
Label1.Text = "狀態:錯誤 - 未選擇操作類型"
TextBox3.Text = "錯誤:請選擇檔案操作類型"
Return
End If
' 更新狀態
Label1.Text = "狀態:執行中..."
' 使用委派執行檔案操作
Dim result As String = currentFileOperation.Invoke(filePath, parameter)
' 顯示結果
Label1.Text = "狀態:操作完成"
TextBox3.Text = result
' 記錄操作
Dim logEntry As String = $"[{DateTime.Now:HH:mm:ss}] {ComboBox1.SelectedItem}: {Path.GetFileName(filePath)}"
operationLog.Add(logEntry)
UpdateOperationLog()
Catch ex As Exception
Label1.Text = "狀態:操作失敗"
TextBox3.Text = $"執行操作時發生錯誤:{ex.Message}"
End Try
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
' 開啟檔案選擇對話框
Using openFileDialog As New OpenFileDialog()
openFileDialog.Title = "選擇檔案"
openFileDialog.Filter = "所有檔案 (*.*)|*.*|文字檔案 (*.txt)|*.txt"
If openFileDialog.ShowDialog() = DialogResult.OK Then
TextBox1.Text = openFileDialog.FileName
Label1.Text = "狀態:已選擇檔案"
End If
End Using
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
' 清除所有輸入
TextBox1.Clear()
TextBox2.Clear()
TextBox3.Text = "已清除所有輸入內容"
Label1.Text = "狀態:已清除輸入"
End Sub
Private Sub UpdateOperationLog()
' 更新操作記錄顯示
ListBox1.Items.Clear()
' 只顯示最近的 10 筆記錄
Dim startIndex As Integer = Math.Max(0, operationLog.Count - 10)
For i As Integer = startIndex To operationLog.Count - 1
ListBox1.Items.Add(operationLog(i))
Next
' 自動捲動到最新記錄
If ListBox1.Items.Count > 0 Then
ListBox1.TopIndex = ListBox1.Items.Count - 1
End If
End Sub
End Class
使用的控制項:
- TextBox1:輸入檔案路徑。
- TextBox2:輸入檔案內容或目標路徑。
- ComboBox1:選擇檔案操作類型。
- Button1:執行檔案操作。
- Button2:瀏覽選擇檔案。
- Button3:清除所有輸入。
- ListBox1:顯示操作記錄。
- Label1:顯示操作狀態。
- Label2:顯示目前操作類型。
- TextBox3:顯示操作結果(多行文字框)。
這個範例展示了 AddressOf 的實際價值:
- 統一介面:所有檔案操作都透過相同的委派介面 FileOperationDelegate 進行
- 動態切換:使用者選擇不同操作時,程式自動切換對應的處理方法
- 易於擴充:要新增檔案操作功能,只需要寫新方法並在 UpdateCurrentOperation 中加一行
- 程式碼清晰:Button1_Click 中的邏輯簡潔明瞭,沒有複雜的條件判斷
- 完整輸出:所有結果都透過 Label 和 TextBox 控制項顯示,符合 Windows Forms 應用程式規範