1
votes

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

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);
}