38

I have a dataGridView when I click on any row a form is opened to update the row data, but after ending updates the updating form is closed but the dataGridView data is not updated

How can i do that ?

Can Poyrazoğlu
  • 33,241
  • 48
  • 191
  • 389
amer
  • 613
  • 3
  • 7
  • 10

10 Answers10

54

BindingSource is the only way without going for a 3rd party ORM, it may seem long winded at first but the benefits of one update method on the BindingSource are so helpful.

If your source is say for example a list of user strings

List<string> users = GetUsers();
BindingSource source = new BindingSource();
source.DataSource = users;
dataGridView1.DataSource = source;

then when your done editing just update your data object whether that be a DataTable or List of user strings like here and ResetBindings on the BindingSource;

users = GetUsers(); //Update your data object
source.ResetBindings(false);
The Berga
  • 3,744
  • 2
  • 31
  • 34
Paul C
  • 4,687
  • 5
  • 39
  • 55
  • hm, coming over from "simple DataGridView refresh question", this ResetBinding() call still doesn't work with my simple test project ;) Can you give an actual, buildable, working example of this doing the refresh properly? – Alan Oct 09 '11 at 08:46
  • 4
    ResetBindings seems to work only with .net types. I think if you use a custom collection you need to implement the IBindingList interface, but i haven't tried that yet. – Ed Sykes Jan 11 '12 at 13:12
  • What do you mean by custom collection? – Paul C Jan 11 '12 at 16:58
  • Haven't tried per @EdSykes `IBindingList` suggestion, but this does *not* work with `BindingList` either unfortunately. – Toby Sep 20 '17 at 12:21
  • I thought that converting all my dataGrids would be painful, but is wasnt. Thank you.:) – TomeeNS Nov 04 '21 at 20:21
39

Rebind your DatagridView to the source.

DataGridView dg1 = new DataGridView();
dg1.DataSource = src1;

// Update Data in src1

dg1.DataSource = null;
dg1.DataSource = src1;
Ian
  • 33,605
  • 26
  • 118
  • 198
  • This is just an example, you only want the bottom two rows, and you want them after an update. So imagine on the parent, on the child closing event. – Ian Aug 10 '11 at 10:45
  • This is how I used to do it and it does work fine but I found having a 'BindingSource' with that one 'ResetBindings' method (as per my answer) superb! – Paul C Aug 16 '11 at 14:38
  • 1
    @Ian: it might be worth updating your example and mentioning that if one nulls out the DataSource property, then they lose the schema (columns). It's usually better to set it to typeof(ElementType), where ElementType is the type of bound rows. – Alan Oct 09 '11 at 08:44
  • although it works but you have to resetting some properties of your datagridview such as column header text, column size and visibility of some column such as id and ... – Vahid Ghadiri Nov 18 '11 at 17:43
6

I know thats an old topic but i suddenly found the best way of doing it and it does not require nullifying the datasource and reassigning it. Just use a BindingList instead of a List.

for example:

//declare your list
private BindingList<myclass> mMyList = new BindingList<myclass>();

//then bind it to your datagrid, i usually do it on the Load event
private void Form1_Load(object sender, EventArgs e)
{
    _dgMyDatagrig.DataSource = mMyList;
}

//start populating your list 
private void addItem(mycclass item)
{
    mMylist.add(item);

//the datagrid will show automatically the new added/updated items, no need to do anything else

}
Kutu
  • 161
  • 1
  • 8
4

I know i am late to the party but hope this helps someone who will do the same with Class binding

var newEntry = new MyClassObject();

var bindingSource = dataGridView.DataSource as BindingSource;
var myClassObjects = bindingSource.DataSource as List<MyClassObject>;
myClassObjects.Add(newEntry);
bindingSource.DataSource = myClassObjects;

dataGridView.DataSource = null;
dataGridView.DataSource = bindingSource;
dataGridView.Update();
dataGridView.Refresh();
BMaximus
  • 1,062
  • 1
  • 11
  • 19
2

I use the DataGridView's Invalidate() function. However, that will refresh the entire DataGridView. If you want to refresh a particular row, you use dgv.InvalidateRow(rowIndex). If you want to refresh a particular cell, you can use dgv.InvalidateCell(columnIndex, rowIndex). This is of course assuming you're using a binding source or data source.

1

You can use the DataGridView refresh method. But... in a lot of cases you have to refresh the DataGridView from methods running on a different thread than the one where the DataGridView is running. In order to do that you should implement the following method and call it rather than directly typing DataGridView.Refresh():

    private void RefreshGridView()
    {
        if (dataGridView1.InvokeRequired)
        {
            dataGridView1.Invoke((MethodInvoker)delegate ()
            {
                RefreshGridView();
            });
        }
        else
            dataGridView1.Refresh();
    }  
0

I don't know if this has really been solved or not... but by looking at all the other answers, nothing seems quite clear. The best way I found to do this is to put the same code, that was used to populate your datagridview into a method and pass it your form's datagridview, as so:

public void ConnectAndPopulateDataGridView(DataGridView dataGridView)
{ }

The code within the method is the exact same as the code used to populate the datagirdview originally, except for the datagridview name changing to whatever you called it in your method.

Now this method is called in your parent form.

The child form is launched via a .ShowDialog() then the method is called after so that it is called right after the child for is closed... as so:

ChildForm.ShowDialog();

ConnectAndPopulateDataGridView(dataGridView1);
Meiko Rachimow
  • 4,664
  • 2
  • 25
  • 43
Bragon
  • 11
  • 4
0

I found this useful .NET documentation that demonstrates how to reset the bindings correctly, using BindingSource.ResetBindings.

Karlomanio
  • 344
  • 4
  • 11
-1

You just need to redefine the DataSource. So if you have for example DataGridView's DataSource that contains a, b, i c:

DataGridView.DataSource = a, b, c

And suddenly you update the DataSource so you have just a and b, you would need to redefine your DataSource:

DataGridView.DataSource = a, b

I hope you find this useful.

Thank you.

miksiii
  • 2,426
  • 26
  • 22
-1

You can use SqlDataAdapter to update the DataGridView

     using (SqlConnection conn = new SqlConnection(connectionString))
        {
            using (SqlDataAdapter ad = new SqlDataAdapter("SELECT * FROM Table", conn))
            {
               DataTable dt = new DataTable();
                 ad.Fill(dt);
               dataGridView1.DataSource = dt;
            }
        }