views:

288

answers:

2

I want to cache a DataGridView row between 'refreshes' i.e. between a Rows.Clear() and a Columns.Clear(). However it seems that calling the Clear() methods does not unbind the data from the DataGridView instance, An example,


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        DataGridViewRow cachedRow = new DataGridViewRow();

        private void button1_Click(object sender, EventArgs e)
        {
            this.dataGridView1.Rows.Clear();
            this.dataGridView1.Columns.Clear();
            DataGridViewColumn aColumn = new DataGridViewTextBoxColumn();
            this.dataGridView1.Columns.Add(aColumn);
            this.dataGridView1.Rows.Add(cachedRow);
        }
    }

This is done on a Form containing a DataGridView and a Button. Clicking the button twice gives the "Row provided already belongs to a DataGridView" error.

There has been some discussion online about this that suggests that it may be a bug, however this was around 2004.

+2  A: 

Once a row is part of a gridview, you can't re-add it. The row itself keeps track of what DataGridView it is in. I would suggest making a copy of the cached row and adding the copy to the view. Since you make a new copy each time it won't be in the view. Alternatively, you can go through and remove only those rows that have not been cached from the view, leaving the cached rows behind so that you don't need to re-add it.

tvanfosson
The link given is to a DataRow method, not a DataGridViewRow method. Is this also the case for DataGridViewRows as well?
Brendan
Sorry. The principle is the same -- it does keep track. I've updated the post and link.
tvanfosson
A: 

I'm not sure why you'd want this behviour? You should only remove the rows in the grid that you want to remove.

You should look into implementing ObservableCollection and a Binding component. This way, if an item is removed from your object model, then it is automatically removed from the grid. This saves you having to perform what sounds like manual data binding and avoids this problem altogether.

If you're using DataSet or typed DataSets, then the observable functionality is already implemented for you - you just need to bind the datatable to the grid. If you have a table object in memory, you'll notice that you can load another one, then use the DataTable.Merge function to combine the results.

Neil Barnwell
My dialog previews a CSV file of numerical data in a read-only DataGridView. If the headers are not in the preview it can include an editable line where the user can input their own headers. This may be switched off/on and needs to be cached in these cases
Brendan
In that case, I'd *always* filter the headers out of the input prior to binding, and use the file contents to build actual column headers for the grid.
Neil Barnwell
The dialog is one to parse an arbitrary CSV file, the file may not include headers at all - hence the option to add some. I tried using a separate cache list of cell contents but it turned out to be a lot of hassle keeping the two concurrent.
Brendan