一直以來開發C# .Net表單程式, 比較容易搞混的觀念( 對於一路寫VB.Net的人來說啦~ )
那麼底下我們就來講解一下甚麼是委派與事件吧!
程式範例出自: Visual C# 2015 學習經典/松崗出版
作者做了些許的更改。
用途:
當你要呼叫Subroutine與被呼叫Subroutine之間需要一個媒介時,委派就是很好用的方法。
範例資源:
概念:
[委派] 白話說明:
工廠裡面廠長(有主控權) 將這個禮拜的任務單據, 送給底下課長(媒介) 去指派任務給基層的操作人員(參數)去操作機器。
必須要透過個有職位抬頭的人物, 去傳達這件事情, 這個事情包含了很多任務。
委派的宣告結構
以下講解的範例, 我們用國小國中數學常用的三角形, 長方形面積算法作為函式, 方法之內容。
Public delegate double DArea(int d1, int d2); 委派結構_對應其他方法
Demo 畫面
Program.cs 的程式碼
namespace DelegatedTest
{
internal static class Program
{
/// <summary>
/// 應用程式的主要進入點。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public delegate double DArea(int d1, int d2);
public static void GetArea(int x, int y, DArea tv)
{
double area = tv(x, y);
Console.WriteLine("高:{0}, 底:{1}, 面積:{2} \n", x, y, area);
}
}
}
Form1.cs的程式碼
namespace DelegatedTest
{
public partial class Form1 : Form
{
double TriArea; // 三角形的面積(可能有小數點)
double RecTArea; // 長方形的面積(可能有小數點)
public Form1()
{
InitializeComponent();
}
// 三角形算式
public static double TriA(int H, int B)
{
return (H * B / 2);
}
// 長房形算式
public static double RecA(int L, int W)
{
return (L * W);
}
private void caculate_bt_Click(object sender, EventArgs e)
{
// 判斷三角形的
if (!string.IsNullOrEmpty(trianHiegh_textBox.Text) && !string.IsNullOrEmpty(trianBottom_textBox.Text))
{// 2個 TextBox都有字串資料
TriArea = TriA(Convert.ToInt16(trianHiegh_textBox.Text), Convert.ToInt16(trianBottom_textBox.Text));
TriaArea_textBox.Text = Convert.ToString(TriArea);
}
else
{
MessageBox.Show("至少有一個 三角形的TextBox 沒有資料");
}
if (!string.IsNullOrEmpty(RectHiegh_textBox.Text) && !string.IsNullOrEmpty(RectWidth_textBox.Text) )
{
if (Convert.ToInt16((RectHiegh_textBox.Text))!= Convert.ToInt16((RectWidth_textBox.Text)))
{
RecTArea = RecA(Convert.ToInt16((RectHiegh_textBox.Text)),Convert.ToInt16((RectWidth_textBox.Text)));
RectanArea_textBox.Text = Convert.ToString(RecTArea);
}
else
{
MessageBox.Show("至少有一個 長方形的TextBox 2邊輸入一樣的數字。");
}
}
else
{
MessageBox.Show("至少有一個 長方形的TextBox 沒有資料");
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
} 解釋
TriA(int1,int2)方法, RectA(int1,int2)方法,
對應委派類別函式 DArea(int1,int2)
參數資料形態是一樣的, 這樣才能確保委派過去的資料型態是一樣。
TriA : 處理三角形面積算法。
RectA : 處理矩形面積算法。
從檔案總管的 Program.cs 引用裡面的 method
引用到 Windows Form 類別內做為使用.
1. static method 引用法
2. non-static 引用法
c# – accessing a function in the Program.cs that initializes my Form1 from my Form1 – Stack Overflow
在C#中,事件處理程序通常使用 += 或是 -=運算子來訂閱事件,並使用 delegate 或匿名方法來定義處理程序。以下第一個範例:
定義了一個委託類型 EventHandlerDelegate,它將用於定義事件的類型:
// 定義一個委託,用於處理事件
public delegate void EventHandlerDelegate(object sender, EventArgs e); 接下來,我們創建了一個自定義的按鈕類別 MyButton,並且宣告了一個事件 ButtonClicked,並將 EventHandlerDelegate 用作事件類型:
//創建一個自定義的按鈕類別
public class MyButton
{
// 宣告一個事件,使用上方的委派類型 作為我們的事件類型。
public event EventHandlerDelegate ButtonClicked;
// 模擬一個按鈕點擊的方法!
public void SimulateButtonClick()
{
Console.WriteLine("按鈕被點擊了!");
// 檢查是否有註冊事件處理程序,然後調用它們
if (ButtonClicked != null)
{
//包含事件資料之類別的基底類別,全部清空
EventArgs e = EventArgs.Empty;
ButtonClicked(this, e);
}
}
}
在SimulateButtonClick() 方法中,我們模擬了按鈕的模擬點觸事件,然後使用ButtonClicked 事件來通知註冊的事件處理事件。
最後,在 Main 方法中,我們註冊了一個事件處理程序 Button_Clicked,當按鈕點擊事件發生時,這個處理程序將被調用。使用 Invoke 方法來觸發事件處理程序也是可能的,特別是當多個執行緒涉及時,它可以更安全地調用處理程序:
public class Program
{
public static void Main()
{
MyButton button = new MyButton();
// 註冊事件處理程序
button.ButtonClicked += Button_Clicked;
// 模擬按鈕點擊
button.SimulateButtonClick();
}
// 事件處理程序
public static void Button_Clicked(object sender, EventArgs e)
{
Console.WriteLine("事件處理程序被觸發!");
}
}
No.2 創建一個加減乘_四則運算範例
這範例中,先定義了一個委託 Calculate,這個委託具有兩個整數參數和一個整數返回值。接著定義了一個事件 StartEvent,這個事件使用 Calculate 委託作為事件類型。
delegate int Calculate(int x, int y);
static event Calculate StartEvent; 這個部分定義了委託和事件,用於計算兩個整數之間的操作。
接下來,在 Main 方法中,我們定義了兩個整數變數 x 和 y,它們的值分別為 1 和 2。然後,我們註冊了兩個事件處理程序,分別是 Add 和 Multiply,這兩個處理程序都是將兩個整數進行不同的操作。
int x = 1;
int y = 2;
StartEvent += Add;
StartEvent += Multiply; 接著,我們使用 Invoke 方法來觸發 StartEvent 事件,傳遞 x 和 y 作為參數。這將導致兩個事件處理程序(Add 和 Multiply)被呼叫,並分別執行加法和乘法操作。
StartEvent.Invoke(x, y); 最後,我們使用 Console.ReadKey() 來等待使用者的輸入,以確保控制台應用程序保持運行狀態。
using System;
delegate int CalculationOperation(int x, int y);
static event CalculationOperation CalculationRequested;
static void Main(string[] args)
{
int operand1 = 1;
int operand2 = 2;
// 註冊事件處理程序
CalculationRequested += Add;
CalculationRequested += Multiply;
// 觸發事件並獲取計算結果
int result = Calculate(operand1, operand2);
Console.WriteLine("計算結果: " + result);
Console.ReadKey();
}
static int Add(int x, int y)
{
return x + y;
}
static int Multiply(int x, int y)
{
return x * y;
}
static int Calculate(int x, int y)
{
if (CalculationRequested != null)
{
int result = 0;
foreach (CalculationOperation operation in CalculationRequested.GetInvocationList())
{
result = operation(x, y);
}
return result;
}
return 0;
}
Caculate方法,該方法處理事件的觸發和多個事件處理程序的處理。這樣可以更清晰地顯示了事件處理程序的用途,並提供了更好的語意。
import 與 export 在Node.js 有提到其用法: Node.js require、module以及exports 模組設定 - Hugo Habor 每一個Javascript檔案可當作獨立模組系統(ES Module) 1. Module(模組)…
作者今天遇到一個很奇怪的問題 寫程式寫到一半... 點擊應用程式時... 怎麼都跳不出畫面... 後來查詢了一下是Reg註冊可能被微軟更新給搞掉了... 文章資訊來源: 【以解決】各位.exe檔案打不開,不要相信"在 Windows 7 或 Windows Vista 中無法打開 .EXE 檔案"這篇文章…
Node.js可以提供你很多模組,今天來探索如何使用 Node.js 的 http 模組來架設一個簡單的伺服器。 本篇使用模組require 載入你所需要的模組。這次我們使用'http' 模組來創造一個簡單的server。 資料參考 Node.js - createServer 起手式 - iT…
針對Node.js來談談 require、module以及exports 模組設定。這些概念允許開發者將大型程序分解成小的、可管理的、可重用的部分,稱為模塊。 下面將逐一介紹這些概念,以及它們如何與 JavaScript 關聯。 An Essential Guide to Node.js Modules (javascripttutorial.net) 1. Module(模組)…
像是很多專案必須讀取國家資料中心的metadata,許多檔案格式為CSV、JSON、Html可以利用網頁技術去爬蟲;拿一個範例來嘗試看看就知道這些語法的實際用途。 [主題週]專題報導-開放資料 (Open Data)相關議題與應用 (114230) - Cool3c 在這裡我們使用台北市資料大平台 UBike2.0 作為資料依據! 目的 來抓取空位數量 >15, 抓取空位數量 <15。…