Как удалить из таблицы csv на основе удаления из datagridview?

#c# #winforms #csv #datagridview

Вопрос:

У меня есть сетка данных, которая сохраняет свои данные в файле csv при закрытии приложения и извлекает их при загрузке. У меня есть кнопка, которая удаляет строки из сетки данных с помощью кода, показанного ниже. Когда я вызываю метод удаления, строка удаляется из сетки данных, но не из файла csv. Это означает, что при перезапуске приложения данные загружаются обратно в сетку данных, но не задается правильный индекс и выдает эту ошибку:

System.NullReferenceException: 'Object reference not set to an instance of an object.' System.Windows.Forms.DataGridViewCell.Value.get returned null.

Как я могу изменить инструкцию delete, чтобы она удаляла как строку в представлении datagrid, так и конкретную строку из моего csv-файла, чтобы она не отображалась при перезагрузке приложения?

     private void DeleteItem()
    {
        var dataGrid = dataGridViewRegisteredVehicles;
        foreach (DataGridViewCell oneCell in dataGrid.SelectedCells)
        {
            if (oneCell.Selected)
            {
                dataGrid.Rows.RemoveAt(oneCell.RowIndex);
                GetSumOfCost();
            }
        }
    }
 

Вот код, в котором хранятся данные:

     public void Store(MainForm form)
    {
        var data = form.dataGridViewRegisteredVehicles;

        using (var temp = new FileStream(@"C:tempData.csv", FileMode.OpenOrCreate, FileAccess.ReadWrite))
        {

            TextWriter write = new StreamWriter(temp);
            for (int rows = 0; rows < data.Rows.Count; rows  )
            {
                for (int columns = 0; columns < data.Columns.Count; columns  )
                {
                    write.Write("t"   data.Rows[rows].Cells[columns].Value.ToString()   "t"   "|");
                }
                write.WriteLine("");
            }
            write.Close();
        }

    }
 

А вот код, который извлекает данные:

  public void Load(MainForm form)
    {
        string[] lines = File.ReadAllLines(@"C:tempData.csv");
        string[] data;

        for (int i = 0; i < lines.Length; i  )
        {
            data = lines[i].ToString().Split('|');

            string[] row = new string[data.Length];

            for (int j = 0; j < data.Length; j  )
            {
                row[j] = data[j].Trim();
            }
            form.dataGridViewRegisteredVehicles.Rows.Add(row);
        }
    }
 

Комментарии:

1. Нет, он не обновляет данные из таблицы должным образом, если вы используете этот метод

2. Похоже, что вы «цитируете» поле с помощью вкладки и разделяете его по каналу, когда пишете. Вы не делаете то же самое, когда читаете. Это приведет к избытку пробелов при каждом цикле чтения/записи

Ответ №1:

Проще, если вы забудете CSV и вместо этого используете XML-файл:

  • Создайте новую форму
  • Поместите представление datagrid в свою форму
  • Поместите этот код в событие FormClosing (дважды щелкните FormClosing в конструкторе форм, в молнии сетки свойств после нажатия на фон формы).
     (dataGridView1.DataSource as DataTable).WriteXml("grid.xml");
 
  • Поместите этот код в событие FormLoad:
     var dt = new DataTable();
    if(File.Exists("grid.xml")){
      dt.ReadXml("grid.xml");
    } else {
      dt.Columns.Add("Name");
      dt.Columns.Add("Age");
    }
    dataGridView1.DataSource = dt;
 

Поэтому, когда вы удаляете строку из сетки, она удаляется из таблицы данных. Исчезновение из таблицы данных означает, что она не записана в файл. При следующем открытии программы строка отсутствует

Это использует встроенную возможность для datatable самостоятельно записывать/считывать данные из xml-файла. Если вы хотите расширить его до создания csv вместо этого, вы можете объединить существующий код