首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

WinForms 多窗體數據傳遞:主窗體向子窗體推送數據的標準模式

     編輯:程式設計綜合問答

場景

`FrmMain` 按鈕點擊獲取信息,需實時顯示在已打開的 `FrmShow` 窗體中。

方案一:公共方法/屬性(最簡單、耦合度可控)


// FrmShow.cs
public partial class FrmShow : Form {
    public void UpdateInfo(string message) {
        if (this.InvokeRequired) {
            this.BeginInvoke(new Action(UpdateInfo), message);
            return;
        }
        txtDisplay.AppendText(message + Environment.NewLine); // 線程安全更新 UI
    }
}

// FrmMain.cs
private FrmShow showForm;
private void FrmMain_Load(object sender, EventArgs e) {
    showForm = new FrmShow();
    showForm.Show(); // 非模態顯示
}

private void btnGetData_Click(object sender, EventArgs e) {
    string data = GetDataFromSomewhere();
    showForm?.UpdateInfo(data); // 直接調用公共方法
}

方案二:事件/委託(解耦,多訂閱者)


// 共享事件參數類
public class DataEventArgs : EventArgs { public string Message { get; set; } }

// FrmMain 發布事件
public event EventHandler DataReceived;
private void OnDataReceived(string msg) {
    DataReceived?.Invoke(this, new DataEventArgs { Message = msg });
}

// FrmShow 訂閱
public FrmShow(FrmMain main) {
    InitializeComponent();
    main.DataReceived += (s, e) => UpdateInfo(e.Message);
    // 關閉時取消訂閱防內存洩漏
    this.FormClosed += (s, e) => main.DataReceived -= ...;
}

方案三:共享數據模型 + BindingSource(數據驅動 UI)

  • 定義 `class SharedData : INotifyPropertyChanged` 包含可綁定屬性。
  • 主窗體修改模型屬性,子窗體控件 `DataBindings.Add("Text", sharedData, "PropertyName")` 自動同步。
  • 適合複雜表單、多控件綁定同一數據源。

最佳實踐建議

  1. **首選方案一**:單向主→子、邏輯簡單、無須解耦時。
  2. **跨線程更新 UI 必須 `Invoke/BeginInvoke`**,否則拋 `InvalidOperationException`。
  3. 子窗體關閉時置空主窗體引用 (`showForm = null`),避免訪問已釋放對象。
  4. 避免直接訪問子窗體 `Controls` 集合 (`showForm.Controls["txt"].Text = ...`),破壞封裝、脆弱難維護。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved