修改Foreach循环中的集合C#

时间:2016-04-01 08:26:45

标签: 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();
            }
        }
    }
}

这正确地在两个ObseravbleCollections之间进行了更改,但是当我更新现有的ObservableCollection时,我得到一个例外:Collection was modified; enumeration operation may not execute.

如何防止这种情况发生并仍然修改原始集合?

1 个答案:

答案 0 :(得分:5)

当您只设置元素的属性时,无需替换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));
    }

    ...
}

现在更新代码的内部循环可以简化为:

foreach (var emp in Employees)
{
    if (empBuild.ID == emp.ID)
    {
        emp.InBuilding = empBuild.InBuilding;
    }
}

或者你像这样编写整个更新循环:

foreach (var empBuild in EmployeesInBuilding)
{
    var emp = Employees.FirstOrDefault(e => e.ID == empBuild.ID);

    if (emp != null)
    {
        emp.InBuilding = empBuild.InBuilding;
    }
}