Избегайте перезаписи значений внутри ObservableCollection (C #, WPF) - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть список рабочих дней

enter image description here

привязка к 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 два результата с одинаковой датой , тогда в MyConceptItems отображается толькоодин (последний) элемент, вероятно, перезаписан.

Пример :

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 голосов
/ 24 сентября 2018

Вы выполняете итерацию по ObservableCollection со строкой

foreach (var existingItem in MyConceptItems) {

Для циклического выполнения таким образом используется итератор коллекции.Затем вы добавляете элемент в этот цикл:

MyConceptItems.Add(new MyDataConcept(...

Вы не можете использовать перечислитель коллекции, пока вы изменяете саму коллекцию (изменение свойств элемента в коллекции - это нормально).

Рассмотрите возможность изменения кода для использования одного из этих удобных IList методов расширения, которые позволяют указывать предикат (условие для выбора определенного объекта): Содержит , Любой, Выберите или SingleOrDefault .Если эти методы не возвращают ожидаемый элемент, вы можете добавить новый элемент в коллекцию.

0 голосов
/ 24 сентября 2018

Нельзя изменить коллекцию при ее перечислении с использованием цикла 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);
    }
}
...