避免覆盖ObservableCollection(C#,WPF)中的值

时间:2018-09-24 10:22:51

标签: c# wpf data-binding observable observablecollection

我有工作日列表

this answer

绑定到DataGrid

ItemsSource="{Binding Path=MyConceptItems}"

然后我从json其他列表中获取并尝试使用日期进行匹配:

public ObservableCollection<MyDataConcept> MyConceptItems { get; set; }

public void GetSheet(string fd, string ld){
 string period = "\"" + fd + "\",\"" + ld + "\"";
 string result = Task.Run(() => MyMethodAsync("getsheet", GetApiKeyAsync(), "," + period)).
                                GetAwaiter().GetResult();
 MyObject resultparsed = new JavaScriptSerializer().Deserialize<MyObject>(result);

  foreach (var item in resultparsed.result.items) {                
   foreach (var existingItem in MyConceptItems) {
    if (existingItem.DateColumn == item.entryDate) {
                    existingItem.PColumn = item.pName;
                    existingItem.TColumn = item.aName;
                    existingItem.HSpend = item.formattedDuration;
 }}}};

我的问题是:当我从json中获得两个具有相同日期的结果时,则仅显示一个(最后一个)项目,可能会被覆盖。

示例

MyConecptItems

  Date     | PColumn
2018-09-03 |  A2
2018-09-04 |  B
2018-09-05 |  C2

来自Json

   Date     | PName
2018-09-03  |  A
2018-09-03  |  A2
2018-09-04  |  B
2018-09-05  |  C
2018-09-05  |  C2

更新:

我正在尝试执行以下操作:

foreach (var item in resultparsed.result.items) {                
   foreach (var existingItem in MyConceptItems) {
    if (existingItem.DateColumn == item.entryDate) 
     if (existingItem.IsExist == false){
                            existingItem.IsExist = true;
                            existingItem.ProjectColumn = item.projectName;
                            existingItem.TaskColumn = item.activityName;
                            existingItem.HoursSpend = item.formattedDuration;
      }
      else
      {
      MyConceptItems.Add(new MyDataConcept(item.entryDate, item.entryDayName, 
                         item.projectName, item.activityName, item.formattedDuration); 
      } 
 }}

但是有以下消息:

System.InvalidOperationException: 
'Collection was modified; enumeration operation may not execute.'

2 个答案:

答案 0 :(得分:1)

使用foreach循环枚举集合时,您无法对其进行修改。尝试这样的事情:

foreach (var item in resultparsed.result.items)
{
    var existingItem = MyConceptItems.FirstOrDefault(x => x.DateColumn == item.entryDate);
    if(existingItem != null)
    {
        //update properties...
    }
    else
    {
        //add new item
        MyConceptItems.Add(new MyDataConcept(item.entryDate, item.entryDayName,
            item.projectName, item.activityName, item.formattedDuration);
    }
}

答案 1 :(得分:0)

您正在用该行遍历ObservableCollection

foreach (var existingItem in MyConceptItems) {

以这种方式循环使用集合的迭代器。然后,您要在该循环中添加一个项目:

MyConceptItems.Add(new MyDataConcept(...

修改集合本身时,不能使用集合枚举器(修改集合中项目的属性就可以了)。

请考虑更改代码以使用以下便捷的IList扩展方法之一,这些扩展方法可让您指定谓词(选择特定对象的条件):ContainsAny,{ {3}}或Select。如果这些方法未返回您期望的项目,则可以将新项目添加到集合中。