将包装对象的集合与一组未包装的对象同步

Ken*_*ran 9 c# collections synchronization

我有两个班:EmployeeEmployeeGridViewAdapter.Employee由几种复杂类型组成.EmployeeGridViewAdapter包装单个Employee并将其成员公开为一组扁平的系统类型,以便DataGridView可以处理显示,编辑等.

我正在使用VS的内置支持将POCO转换为数据源,然后将其附加到BindingSource对象.当我附加DataGridViewBindingSource它时创建预期的列,并在运行时我可以执行预期的CRUD操作.到目前为止一切都很好.

问题是适配器的集合和员工的集合没有被同步.因此,我创建运行时的所有员工永远不会被持久化.这是生成EmployeeGridViewAdapters 集合的代码片段:

        var employeeCollection = new List<EmployeeGridViewAdapter>();
        foreach (var employee in this.employees)
        {
            employeeCollection.Add(new EmployeeGridViewAdapter(employee));
        }
        this.view.Employees = employeeCollection;
Run Code Online (Sandbox Code Playgroud)

非常简单,但我无法弄清楚如何将更改同步回原始集合.我想已经处理了编辑,因为两个集合都引用了相同的对象,但创建新员工和删除员工的情况并没有发生,所以我无法确定.

Mor*_*ner 1

第一个问题似乎是您正在创建一个新列表并将数据绑定到该列表。当您添加元素时,这些元素将被添加到集合中,但您的原始员工列表保持不变。

为了避免这种情况,您应该提供一个自定义集合类,将更改迁移回底层员工列表,或者在数据绑定到它之前连接适当的事件(以在插入/删除时进行迁移)。

为了避免将可编辑集合绑定到网格时出现许多其他问题,您应该实现数据绑定接口,如下所述。这些界面的存在允许可视化控件通知底层集合有关“插入已取消”(当用户中止输入新记录时)等操作,并且类似地允许信息沿相反方向流动(当集合或单独操作时更新 UI)条目发生变化)。

首先,您需要在数据绑定集合中的各个项目上至少实现 IEditableObject、INotifyPropertyChanged 和 IDataErrorInfo,在您的情况下,该集合将是 EmployeeGridViewAdaper 类。

此外,您希望您的集合实现 ITypedList 和 INotifyCollectionChanged。BCL 包含一个 BindingList 实现,它为此提供了一个良好的起点。建议使用它而不是简单的列表。

我可以推荐《Data Binding with Windows Forms 2.0》,以全面介绍该主题。