CBr*_*eze 2 c# wpf foreach observablecollection
我ObservableCollection在foreach循环期间更新项目时遇到问题.基本上我有一个ObservableCollection员工,他们的模型中有一个领域决定他们是否在建筑物中.
我一直在查看数据库表来检查每个员工,看看这个状态是否有任何变化.这就是我这样做的方式C#;
public ObservableCollection<EmployeeModel> EmployeesInBuilding {get; set; }
public ObservableCollection<EmployeeModel> Employees {get; set; }
var _employeeDataService = new EmployeeDataService();
EmployeesInBuilding = _employeeDataService.GetEmployeesInBuilding();
foreach (EmployeeModel empBuild in EmployeesInBuilding)
{
foreach (EmployeeModel emp in Employees)
{
if (empBuild.ID == emp.ID)
{
if (empBuild.InBuilding != emp.InBuilding)
{
emp.InBuilding = empBuild.InBuilding;
int j = Employees.IndexOf(emp);
Employees[j] = emp;
employeesDataGrid.Items.Refresh();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这正确地选择了两者之间的变化ObseravbleCollections,但是当我去更新现有的时,ObservableCollection我得到一个异常:Collection was modified; enumeration operation may not execute.
如何防止这种情况发生并仍然修改原始集合?
Employees只需设置元素的属性,就无需替换集合中的元素.
而不是那样,您的EmployeeModel类应该实现INotifyPropertyChanged接口并PropertyChanged在InBuilding属性更改时引发事件:
public class EmployeeModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool inBuilding;
public bool InBuilding
{
get { return inBuilding; }
set
{
if (inBuilding != value)
{
inBuilding = value;
OnPropertyChanged("InBuilding");
}
}
}
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
...
}
Run Code Online (Sandbox Code Playgroud)
现在更新代码的内部循环可以简化为:
foreach (var emp in Employees)
{
if (empBuild.ID == emp.ID)
{
emp.InBuilding = empBuild.InBuilding;
}
}
Run Code Online (Sandbox Code Playgroud)
或者你像这样编写整个更新循环:
foreach (var empBuild in EmployeesInBuilding)
{
var emp = Employees.FirstOrDefault(e => e.ID == empBuild.ID);
if (emp != null)
{
emp.InBuilding = empBuild.InBuilding;
}
}
Run Code Online (Sandbox Code Playgroud)