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

C# 跨窗體訪問控件:公共屬性/方法封裝法與線程安全實現

     編輯:程式設計綜合問答

錯誤示範

直接將控件 Modifiers = Public,在另一窗體 form1.dataGridView1.Rows.Add(...) —— 破壞封裝、難維護、線程不安全。

正確模式:封裝公共方法

// 窗體 A (擁有 DataGridView)
public partial class MainForm : Form {
    public void AppendRow(string col1, string col2) {
        if (dataGridView1.InvokeRequired) {
            dataGridView1.BeginInvoke((Action)(() => AppendRow(col1, col2)));
            return;
        }
        dataGridView1.Rows.Add(col1, col2);
    }
}

// 窗體 B (調用方)
public partial class ChildForm : Form {
    private MainForm _mainForm;
    public ChildForm(MainForm mainForm) {
        _mainForm = mainForm;
        InitializeComponent();
    }
    private void btnAdd_Click(object sender, EventArgs e) {
        _mainForm.AppendRow("新數據1", "新數據2");
    }
}

進階:事件解耦(推薦)

// 窗體 B 定義事件
public event Action RowAdded;

// 窗體 A 訂閱
var child = new ChildForm();
child.RowAdded += (c1, c2) => AppendRow(c1, c2);
child.Show();

線程安全核心

  • UI 控件只能在創建線程(主線程)訪問。
  • 跨線程調用必須用 Control.Invoke/BeginInvoke 或 SynchronizationContext.Post。
  • BeginInvoke 非阻塞,適合高頻更新;Invoke 阻塞,適合需等待結果場景。

最佳實踐清單

  1. 控件 Modifiers 永遠保持 Private。
  2. 暴露業務語義方法(如 AppendOrder)而非控件操作方法(AddRow)。
  3. 使用 event/delegate 實現雙向解耦,窗體 B 無需引用窗體 A 類型。
  4. 考慮引入 MVVM 框架(如 Prism、MVVM Light)實現 View-ViewModel 分離,徹底消除跨窗體控件訪問。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved