#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 вместо этого, вы можете объединить существующий код