I am building a simple tool to edit a semicolon seperated value files and I use a datagridview to show and edit the data. When I show the data in the datagridview, the text in the last row is shown badly which is weird, because the last row should be empty. This happens when I have AllowUserToAddRows
on true. When I put this property to false, the last row is shown correctly but I want to be able to add rows to the datagridview. I tried to do this with a work around by adding an empty row via clicking a button and then execute the following line of code: DataTable.Rows.Add();
where DataTable is of type DataGridView but then the same rendering issue happens again. And in both cases, when I click the wrongly rendered row and I click a different row, I get an ArgumentOutOfRangeException
on rowIndex
. Is this a bug in the DataGridView and if so, is there a work around for it, where I can load a text-based, semicolon seperated value file in a DataGridView and being able to add lines to it? Or do I have to changes some properties?
1
votes
1 Answers
1
votes
First you need to convert the file to DataTable
correctly.
Then set the DataSource
of the DataGridView
to the data table which you load using the file. Set AllowUserToAddRows
to true an then save the DataTable
back to the file.
Example
Let's say here is the file content:
Column1;Column2
a1;b1
a2;b2
a3;b3
And we expect to show them in a DataGridView
like following:
| Column1 | Column2 |
|=============|============|
|a1 |b1 |
|-------------|------------|
|a2 |b2 |
|-------------|------------|
|a3 |b3 |
|-------------|------------|
| | |
|-------------|------------|
You can simply load and save data using the following code:
DataTable dt;
string fileName = @"d:\file1.txt";
private void Form1_Load(object sender, EventArgs e)
{
dt = LoadFile(fileName);
this.dataGridView1.DataSource = dt;
}
private void SaveButton_Click(object sender, EventArgs e)
{
SaveFile(dt, fileName);
}
LoadFile
DataTable LoadFile(string fileName)
{
var dt = new DataTable();
var lines = System.IO.File.ReadAllLines(fileName);
if (lines.Count() == 0)
return dt;
lines.First().Split(';').ToList().ForEach(x =>
{
dt.Columns.Add(new DataColumn(x));
});
lines.Skip(1).ToList().ForEach(x =>
{
dt.Rows.Add(x.Split(';'));
});
return dt;
}
SaveFile
public void SaveFile(DataTable dt, string fileName)
{
var list = new List<IEnumerable<string>>();
list.Add(dt.Columns.Cast<DataColumn>().Select(x => x.ColumnName));
list.AddRange(dt.Rows.Cast<DataRow>().Select(x => x.ItemArray.Cast<string>()));
var lines = list.Select(x => string.Join(";", x));
System.IO.File.WriteAllLines(fileName, lines);
}