主視窗接收串口資料並解析,需即時推送至波形視窗繪圖。原嘗試在波形視窗建立 MainForm frm = new MainForm() 新實例並輪詢 tranTest(),導致取得的永遠是新實例的空資料,而非正在運行主視窗的即時資料。
public class SensorData {
public int SpeedR1 { get; set; }
public int SpeedR2 { get; set; }
public int SpeedSU { get; set; }
public int SpeedAc { get; set; }
public int Reliability { get; set; }
public DateTime Timestamp { get; set; }
}
public partial class MainForm : Form {
public event EventHandler<SensorData> DataReceived;
private void OnDataReceived(SensorData d) => DataReceived?.Invoke(this, d);
private void serialPort1_DataReceived(...) {
// 解析邏輯...
var data = new SensorData { SpeedR1 = ..., Timestamp = DateTime.Now };
BeginInvoke((Action)(() => OnDataReceived(data))); // 切回 UI 執行緒觸發事件
}
}
public partial class WaveForm : Form {
private readonly MainForm _main;
public WaveForm(MainForm main) {
InitializeComponent();
_main = main;
_main.DataReceived += (s, d) => {
// 將 d 加入繪圖緩衝區,觸發 Invalidate()
AddPoint(d);
};
}
}
var wave = new WaveForm(this);
wave.Show();
BeginInvoke 確保事件在 UI 執行緒觸發,波形視窗直接操作 UI 控件安全。| 方案 | 優點 | 缺點 |
|---|---|---|
| 事件驅動(推薦) | 解耦、即時、型別安全 | 需理解事件模型 |
| 靜態類別/單例共享資料 | 簡單 | 強耦合、難測試、全域狀態風險 |
| Timer 輪詢 | 易理解 | 延遲、CPU 浪費、同步問題 |
| ObservableCollection + Binding | WPF/MVVM 原生 | WinForms 需額外包裝 |
C# 多視窗傳值經典教學:新浪部落格範例