在C#中如何在另一个类中使用外部事件获取的List?
我明白你的痛点——事件处理器里拿到的数据,要在另一个类的方法里用,虽然知道跨类访问的基本思路,但卡在了事件上下文里的数据传递这一步。下面给你几个实用的方案,结合代码示例来说明:
既然数据是在事件触发时获取的,那最直接的方式就是在拿到数据后,主动把它传递给需要使用的win类。我们可以给win类加一个接收数据的方法,或者用自定义事件来完成传递。
示例代码:
首先定义win类,添加接收数据的方法和按钮逻辑:
public class win : Form { private IList<Material> _materialList; // 存储物料列表的私有字段 // 按钮点击触发的方法 public void LoadMaterials2DataGrid() { if (_materialList != null) { // 绑定到DataGridView dataGridView1.DataSource = _materialList; } } // 公开方法:让外部类可以把数据传进来 public void UpdateMaterialList(IList<Material> newMaterialList) { _materialList = newMaterialList; } }
然后在事件处理器所在的类中,拿到数据后调用win类的UpdateMaterialList方法:
// 假设你已经实例化了win窗体 private win _myWinForm; // 你的事件处理器方法 private void EventRegisterHandler(object sender, EventArgs e) { // 获取物料列表的逻辑(你的原有代码) IList<Material> materialList = GetMaterialDataFromSource(); // 把数据传递给win类 _myWinForm?.UpdateMaterialList(materialList); }
这样当你点击按钮触发LoadMaterials2DataGrid时,_materialList已经有了最新数据,就能正常绑定到DataGrid了。
如果你的事件处理器所在的类是全局可访问的(比如单例类),可以把materialList_W设为公共静态属性,让win类直接访问。但要注意这种方法耦合度高,多线程环境下需要处理线程安全问题。
示例代码:
事件处理器所在的类:
public class EventHandlerContainer { // 静态公共属性存储物料列表 public static IList<Material> materialList_W { get; private set; } private void EventRegisterHandler(object sender, EventArgs e) { materialList_W = GetMaterialDataFromSource(); } }
win类的按钮方法:
public void LoadMaterials2DataGrid() { if (EventHandlerContainer.materialList_W != null) { dataGridView1.DataSource = EventHandlerContainer.materialList_W; } }
如果你的项目使用了依赖注入框架(比如Microsoft DI、Autofac),可以把物料列表注册为共享服务,让win类和事件处理器类都注入这个服务,实现数据共享。这种方式解耦性最好,适合中大型项目。
示例代码:
首先在DI容器中注册物料列表:
// 注册为单例,保证全局是同一个实例 services.AddSingleton<IList<Material>, List<Material>>();
事件处理器类通过构造函数注入并更新数据:
public class EventHandlerContainer { private readonly IList<Material> _materialList; // 构造函数注入物料列表 public EventHandlerContainer(IList<Material> materialList) { _materialList = materialList; } private void EventRegisterHandler(object sender, EventArgs e) { // 清空原有数据并添加新数据 _materialList.Clear(); var newMaterials = GetMaterialDataFromSource(); foreach (var mat in newMaterials) { _materialList.Add(mat); } } }
win类注入并使用数据:
public class win : Form { private readonly IList<Material> _materialList; // 构造函数注入物料列表 public win(IList<Material> materialList) { _materialList = materialList; } public void LoadMaterials2DataGrid() { // 用BindingSource包装,确保DataGridView能感知数据变化 dataGridView1.DataSource = new BindingSource(_materialList, null); } }
核心思路就是:把事件处理器中拿到的数据,通过主动传递、全局访问或者依赖注入的方式,让win类能够获取到这个数据实例。优先推荐方案1,耦合度低且逻辑清晰;小型项目可以用方案2;复杂项目建议用方案3来解耦。
内容的提问来源于stack exchange,提问作者Rubens

