Form1 有一個 List<T> dataList,已填充數據。需在 Form2、Form3 中**讀取/修改同一個列表實例**。若在 Form2 中 new List<T>() 會創建新列表,導致數據不同步。
// Form1.cs
public partial class Form1 : Form {
private List<UserData> sharedList = new List<UserData>();
private void btnOpenForm2_Click(object sender, EventArgs e) {
// 關鍵:將共享列表實例傳給 Form2 構造函數
Form2 form2 = new Form2(sharedList);
form2.Show();
}
private void btnOpenForm3_Click(object sender, EventArgs e) {
Form3 form3 = new Form3(sharedList); // 同一實例傳給 Form3
form3.Show();
}
}
// Form2.cs
public partial class Form2 : Form {
private readonly List<UserData> _sharedList; // 只讀字段,持有引用
// 構造函數接收列表引用
public Form2(List<UserData> sharedList) {
InitializeComponent();
_sharedList = sharedList; // 保存引用,不 new 新列表
}
private void Form2_Load(object sender, EventArgs e) {
// 直接使用 _sharedList,讀取/修改即同步到 Form1 和 Form3
dataGridView1.DataSource = _sharedList;
}
private void btnAdd_Click(object sender, EventArgs e) {
_sharedList.Add(new UserData { Name = "New" }); // 修改同步生效
dataGridView1.Refresh();
}
}
// Form3.cs 同理,構造函數接收 List<UserData> sharedList
// 共享數據容器 (單例或依賴注入)
public class SharedDataContext {
public List<UserData> UserList { get; } = new List<UserData>();
public Dictionary<string, Config> Configs { get; } = new Dictionary<string, Config>();
// 事件通知數據變更
public event Action DataChanged;
public void NotifyChanged() => DataChanged?.Invoke();
}
// Form1 持有上下文實例 (或從 IoC 容器獲取)
private readonly SharedDataContext _ctx = new SharedDataContext();
// 打開子窗體傳遞上下文
Form2 f2 = new Form2(_ctx);
Form3 f3 = new Form3(_ctx);
// 子窗體訂閱變更事件實時刷新 UI
public Form2(SharedDataContext ctx) {
InitializeComponent();
_ctx = ctx;
_ctx.DataChanged += OnDataChanged; // 訂閱
LoadData();
}
private void OnDataChanged() => this.Invoke(() => LoadData());
private void Form2_FormClosed(...) => _ctx.DataChanged -= OnDataChanged; // 取消訂閱防洩漏
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 構造函數注入 (推薦) | 顯式依賴、類型安全、易測試、無單例污染 | 需修改構造函數簽名 | 多數 WinForm 多窗體共享場景 |
| 靜態類/單例持有 List | 全局隨處訪問 | 強耦合、難測試、生命週期不可控、多線程不安全 | 極簡單工具類,非業務核心數據 |
| Application.OpenForms 遍歷查找 Form1 取屬性 | 無需修改構造函數 | 極度脆弱、依賴 Form 名稱/類型、運行時易出錯 | 不推薦 |
| 文件/數據庫中轉 | 持久化、跨進程 | 性能差、同步複雜、過度設計 | 需持久化/跨進程共享時 |
lock(_sharedList) 或 ConcurrentBag / BindingList (UI綁定友好)。C# WinForm 多窗體共享 List,核心是「構造函數注入共享實例引用」。 Form1 持有列表實例,創建 Form2/3 時通過構造函數傳入。子窗體保存引用直接操作,修改即時同步。進階場景可封裝 SharedDataContext 統一管理多數據源並提供變更通知事件。拒絕靜態單例、拒絕 Application.OpenForms 硬查找。