theshizy
theshizy

Reputation: 545

Cannot refresh datagridview - an object reference is required

I've been trying to refresh my datagridview on form1 each time form2 closes.

On form 2, I have a close event handler that calls the static method RefreshGridView (which is located in form 1).

private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
    Form1.RefreshGridView();
}

On form 1, I have a static method RefreshGridView to refresh the grid as below.

public static void RefreshGridView()
{
    BindingSource bs = new BindingSource();
    bs.DataSource = dataGridView1.DataSource;
    dataGridView1.DataSource = bs;
}

However each time, I try run my code, I get these error messages at the following lines:

bs.DataSource = dataGridView1.DataSource;

Error: An object reference is required for the non-static field, method, or property 'PGPTool.Form1.dataGridView1'.

dataGridView1.DataSource = bs;

Error: An object reference is required for the non-static field, method, or property 'PGPTool.Form1.dataGridView1'.

How can I go about resolving this?

Upvotes: 1

Views: 1699

Answers (3)

Vland
Vland

Reputation: 4272

Treat your Form2 as a Dialog, it's so much easier. When you've finished dealing with your Form2 call DialogResult.OK. It will also close it.

If your form1 datagridview is bound already to your bs bindingsource, you probably don't need to create a new bindingSource, just query your data again.

public void RefreshGridView()
{
    var q = //your query

    bs.dataSource = q
}

Back in Form1 you have something like this, and you call it every time you want to open Form2:

private void openForm2()
{
    var f2 = new Form2(); //create new form2
    var formResult = f2.ShowDialog(); //open as Dialog and check result after close event
    if (formResult == DialogResult.OK) //check form2 dialog result
    {
        //form2 gave OK, I can update my DGV and display msg
        MessageBox.Show("DGV will be updated", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
        //update my DGV
        RefreshGridView();
    }
    else
    {
        //form2 passed Cancel or something else, not good
        MessageBox.Show("Form2 Closed but nothing happened.", "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    }
}   

Upvotes: 0

Sven Grosen
Sven Grosen

Reputation: 5636

If you don't want Form2 to be given references to Form1, there is another way to do it: event listeners. These will only work if Form1 is responsible for creating instances of Form2 or some central code is responsible for creating both.

So here's how you would do it (if Form1 is creating instances of Form2):

Form2 f2 = new Form2();
f2.FormClosed += (o, e) => { RefreshGridView(); };
//show f2 or do whatever else you need to do with it

If some other class is doing it, you'd have to modify that like this:

//f1 is the instance of Form1
Form2 f2 = new Form2();
f2.FormClosed += (o, e) => { f1.RefreshGridView(); };
//show f2 or do whatever else you need to do with it

As I mentioned in the comments and David mentions in his answer, you need to modify the signature of your RefreshGridView() method to remove the static keyword.

Upvotes: 1

David
David

Reputation: 219037

RefreshGridView shouldn't be a static method, it should be an instance method. And a reference to the instance of form1 should be given to form2. This is because you want this method to make changes to elements on form1, which are part of that instance. (For example, if you have 2 instances of form1, a static method wouldn't know which to modify. Or if you have no instance, it wouldn't have anything to modify.)

So the method should be changed to:

public void RefreshGridView()

And in form2 you should have a way to hold a reference to form1. Something like this:

private Form1 Form1Instance { get; set; }

Since you want to invoke something on this reference every time form2 closes, then is it safe to assume that form2 should require a reference to form1 every time it's created? If so, then you can enforce that in the constructor of form2. Something like this:

public Form2(Form1 form1Instance)
{
    // perform any error checking and/or null checking on form1Instance here

    Form1Instance = form1Instance;
}

Then in the event on form2 you can call the method on that instance:

Form1Instance.RefreshGridView();

Upvotes: 2

Related Questions