C# 将已包装对象集合与未包装对象集合同步
我有两个类:C# 将已包装对象集合与未包装对象集合同步,c#,collections,synchronization,C#,Collections,Synchronization,我有两个类:Employee和EmployeeGridViewAdapter员工由几个复杂类型组成EmployeeGridViewAdapter包装单个Employee并将其成员公开为一组扁平的系统类型,以便DataGridView可以处理显示、编辑等操作 我使用VS的内置支持将POCO转换为数据源,然后将其附加到BindingSource对象。当我将DataGridView附加到BindingSource时,它会创建预期的列,并且在运行时我可以执行预期的CRUD操作。到目前为止一切都很好 问题
Employee
和EmployeeGridViewAdapter
<代码>员工由几个复杂类型组成EmployeeGridViewAdapter
包装单个Employee
并将其成员公开为一组扁平的系统类型,以便DataGridView可以处理显示、编辑等操作
我使用VS的内置支持将POCO转换为数据源,然后将其附加到BindingSource
对象。当我将DataGridView
附加到BindingSource
时,它会创建预期的列,并且在运行时我可以执行预期的CRUD操作。到目前为止一切都很好
问题是适配器集合和员工集合没有同步。因此,我创建的运行时中的所有员工都不会持久化。以下是生成EmployeeGridViewAdapter
集合的代码片段:
var employeeCollection = new List<EmployeeGridViewAdapter>();
foreach (var employee in this.employees)
{
employeeCollection.Add(new EmployeeGridViewAdapter(employee));
}
this.view.Employees = employeeCollection;
var employeeCollection=new List();
foreach(此.employees中的var雇员)
{
添加(新的EmployeeGridViewAdapter(employee));
}
this.view.Employees=employeeCollection;
非常简单,但我不知道如何将更改同步回原始集合。我想编辑已经被处理了,因为两个集合引用了相同的对象,但是创建新员工和删除员工没有发生,所以我不能确定。第一个问题似乎是您正在创建一个新列表并将数据绑定到该列表。添加元素时,这些元素将被添加到集合中,但原始员工列表保持不变 为了避免这种情况,您应该提供一个自定义集合类,将更改迁移回基础员工列表,或者在数据绑定到该列表之前连接适当的事件(在插入/删除时执行迁移) 要避免将可编辑集合绑定到网格时出现许多其他问题,应实现数据绑定接口,如下所述。这些界面的存在允许可视化控件通知底层集合有关操作,例如“插入已取消”(当用户中止新记录的输入时),并且同样允许信息以相反的方向流动(当集合或单个条目更改时更新UI) 首先,您需要在数据绑定集合中的各个项上至少实现IEditableObject、INotifyPropertyChanged和IDataErrorInfo,在您的示例中,这些项是EmployeeGridViewAdaper类 此外,您希望您的集合实现ITypedList和INotifyCollectionChanged。BCL包含一个BindingList实现,它提供了一个很好的起点。建议使用此列表而不是普通列表
我建议您对本主题进行详尽的介绍。您也可以考虑使用和连接它的事件。它可能看起来像这样
ObservableCollection<EmployeeAdapter> observableEmployees =
new ObservableCollection<EmployeeAdapter>();
foreach (Employee emp in employees)
{
observableEmployees.Add(new EmployeeAdapter(emp));
}
observableEmployees.CollectionChanged +=
(object sender, NotifyCollectionChangedEventArgs e) =>
{
ObservableCollection<EmployeeAdapter> views =
sender as ObservableCollection<EmployeeAdapter>;
if (views == null)
return;
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (EmployeeAdapter view in e.NewItems)
{
if (!employees.Contains(view.Employee))
employees.Add(view.Employee);
}
break;
case NotifyCollectionChangedAction.Remove:
foreach (EmployeeAdapter view in e.OldItems)
{
if (employees.Contains(view.Employee))
employees.Remove(view.Employee);
}
break;
default:
break;
}
};
BindingList<EmployeeAdapter> empViews = new BindingList<EmployeeAdapter>();
foreach (Employee emp in employees)
{
empViews.Add(new EmployeeAdapter(emp));
}
empViews.ListChanged +=
(object sender, ListChangedEventArgs e) =>
{
BindingList<EmployeeAdapter> employeeAdapters =
sender as BindingList<EmployeeAdapter>;
if (employeeAdapters == null)
return;
switch (e.ListChangedType)
{
case ListChangedType.ItemAdded:
EmployeeAdapter added = employeeAdapters[e.NewIndex];
if (!employees.Contains(added.Employee))
employees.Add(added.Employee);
break;
case ListChangedType.ItemDeleted:
EmployeeAdapter deleted = employeeAdapters[e.OldIndex];
if (employees.Contains(deleted.Employee))
employees.Remove(deleted.Employee);
break;
default:
break;
}
};
如果你需要这个接口,你也可以使用它并连接它的事件。它可能看起来像这样
ObservableCollection<EmployeeAdapter> observableEmployees =
new ObservableCollection<EmployeeAdapter>();
foreach (Employee emp in employees)
{
observableEmployees.Add(new EmployeeAdapter(emp));
}
observableEmployees.CollectionChanged +=
(object sender, NotifyCollectionChangedEventArgs e) =>
{
ObservableCollection<EmployeeAdapter> views =
sender as ObservableCollection<EmployeeAdapter>;
if (views == null)
return;
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (EmployeeAdapter view in e.NewItems)
{
if (!employees.Contains(view.Employee))
employees.Add(view.Employee);
}
break;
case NotifyCollectionChangedAction.Remove:
foreach (EmployeeAdapter view in e.OldItems)
{
if (employees.Contains(view.Employee))
employees.Remove(view.Employee);
}
break;
default:
break;
}
};
BindingList<EmployeeAdapter> empViews = new BindingList<EmployeeAdapter>();
foreach (Employee emp in employees)
{
empViews.Add(new EmployeeAdapter(emp));
}
empViews.ListChanged +=
(object sender, ListChangedEventArgs e) =>
{
BindingList<EmployeeAdapter> employeeAdapters =
sender as BindingList<EmployeeAdapter>;
if (employeeAdapters == null)
return;
switch (e.ListChangedType)
{
case ListChangedType.ItemAdded:
EmployeeAdapter added = employeeAdapters[e.NewIndex];
if (!employees.Contains(added.Employee))
employees.Add(added.Employee);
break;
case ListChangedType.ItemDeleted:
EmployeeAdapter deleted = employeeAdapters[e.OldIndex];
if (employees.Contains(deleted.Employee))
employees.Remove(deleted.Employee);
break;
default:
break;
}
};
@肯尼斯:你做了什么来解决你的问题?把ObserviewModelCollection解决方案应用到你的问题上怎么样。