На форме есть пустая DataGridView. Создаю для неё DataTable.
private void новыйToolStripMenuItem_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Product"));
dt.Columns.Add(new DataColumn("Prize"));
dt.Columns.Add(new DataColumn("Count"));
dataGridView1.DataSource = dt;
}
Ввожу в строку DataGridView данные и пытаюсь сохранить их в XML.
private void сохранитьToolStripMenuItem_Click(object sender, EventArgs e)
{
DataTable dT = GetDataTableFromDGV(dataGridView1);
DataSet dS = new DataSet();
dS.Tables.Add(dT);
SaveFileDialog save = new SaveFileDialog();
save.Filter = "XML|*.xml";
if (save.ShowDialog(this) == DialogResult.OK)
{
try
{
dS.WriteXml(save.FileName);
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
Метод GetDataTableFromDGV
private DataTable GetDataTableFromDGV(DataGridView dgv)
{
DataTable dt = new DataTable();
foreach (DataGridViewColumn column in dgv.Columns)
{
if (column.Visible)
{
dt.Columns.Add();
}
}
object[] cellValues = new object[dgv.Columns.Count];
foreach (DataGridViewRow row in dgv.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
cellValues[i] = row.Cells[i].Value;
}
dt.Rows.Add(cellValues);
}
return dt;
}
При попытке открыть сохраненный XML
private void открытьToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
if (open.ShowDialog(this) == DialogResult.OK)
{
string path = open.FileName;
ds = new DataSet();
ds.ReadXml(path);
dataGridView1.DataSource = ds.Tables[0].DefaultView;
}
}
Всегда получается, что нет последней Column. В методе GetDataTableFromDGV() указывает на ошибку NullReferenceException в строке:
cellValues[i] = row.Cells[i].Value;
Прочитал, что надо изначально задавать column в DataTable чтобы её избежать, но они уже заданы при создании.
В чем может быть ошибка?
Выкиньте полностью метод GetDataTableFromDGV.
У вас привязан DataTable к DataGridView, вот его и берите:
var dt = (DataTable)dataGridView1.DataSource;
Ещё лучше - сделайте его полем класса (формы).
DataSet тоже можно полностью выкинуть. Я понимаю, почему вы его используете: не получалось читать данные иначе.
Исходя из вопроса и комментариев, я могу предположить, что в файл не записываются те колонки, в которых нет данных. Чтобы решить эту проблему, можно записывать схему вместе с данными. Одновременно решится проблема чтения без датасета.
Запись:
dt.WriteXml(path, XmlWriteMode.WriteSchema);
Чтение:
dt.ReadXml(path);
dataGridView1.DataSource = dt;
Обратите внимание: создавать локальные DataTable не нужно! Мы его сделали полем.
Напомню, что DataSet тоже не нужен.
Осталось исправить ещё одну строку кода, чтобы всё заработало - дать имя дататейблу при его создании:
dt = new DataTable("Products");
Это необходимо в отсутствие датасета.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости