Avatar of annasaru
annasaru
 asked on

To refresh a gridview on the child window form from the nested class in the parent form in C#

I have parent form having toolstrip menu item, the menu items have checked = ture .. if i check one item it will open a new form having gridview in it and datasource of the gridview is linked with dictionary abject on the parent form . My need is whenever there is a new item in the dictionary object i want that item to showed up automatically in the gridview if i have that child form already openend and i am adding the items in the dictioanry object inside the nested class of the parent form . For now if i just uncheck and check the child form from the toolstrip its showing the newly added item in gridview but i don't want to uncheck and check everytime.

Say i have Form1 as a parent form having toolstripmenu item as View, if user check View the new child form (Form2) opens having gridview the datasource of which is linked to dictinary object defined in Form1 ... my need is whenver i have a new item in the dictionary object (which i am adding in the nested class (ClassNested) of parent form(Form1) ) that item should be get displayed automatically in the grid if the Form2 is already openened.

Hope i am not confusing in my questiion. Any help is much appreciated.
C#.NET Programming

Avatar of undefined
Last Comment
annasaru

8/22/2022 - Mon
Imperdonato

I would suggest create a worker thread in your form2, which runs in the background continuously checking if the datasouce is updated. Whenever the datasource is updated in form1 (you can raise an event from form1 or have a static variable in form1 to notify the same to the worker thread), change the dataSource for the datagrid in form2 and rebind the data.

Hope this helps!
annasaru

ASKER
Thanks for reply, but in this case how the gridview in the child form(Form2) refreshes itself ? if you can provide me some sample code for implementing this functionality that would be appreciated.
Imperdonato

Suppose the gridview in form2 is "grdView_Form2".

In your event handler or the method that your worker thread will call when it recognizes that the datasource has been updated,
write this:
grdView_Form2.DataSource = newDataSource;
grdView_Form2.Databind();

Please change the value for newDataSource appropriately according to your code. (As pointed/ hinted earlier, it could be a static variable in your form1 or pass it to your event handler)

Hope this helps!

Your help has saved me hundreds of hours of internet surfing.
fblack61
annasaru

ASKER
I am not sure how can i run a Worker thread in form2 to check for datasource updates and how can i raise an event from form1 or how can i use the static variable in form1 to do the trick for me.
Thanks for all your help.
Imperdonato

If form1:

static Arraylist dataSource = new Arraylist();
static bool isChanged = false;

in Form1_Load method:

dataSource = gridView_Form1.DataSource;

in Form1, whenever your datagrids' datasource changes, add this:
isChanged = true;

in form2, implement thread something like (most probably in your Load method):
Thread t = new Thread (RefreshDataGrid);    
t.Start();                          

also declare the method in form2:
  static void RefreshDataGrid() {    
      if (Form1.isChanged) {
        grdView_Form2.DataSource = Form1.dataSource;
        grdView_Form2.Databind();
          }
   }

Please correct the syntax errors if you encounter any, as I don't have development environment setup here on my machine. But this code will work!

Read  
http://msdn.microsoft.com/en-us/library/ms173178(VS.80).aspx
http://www.codeproject.com/KB/cs/ThreadsinC_.aspx
http://www.codeproject.com/KB/cs/workerthread.aspx
for more details.

annasaru

ASKER
Thanks for the above code but i have few concerns:
 static void RefreshDataGrid() {    
     if (Form1.isChanged) {
       grdView_Form2.DataSource = Form1.dataSource;
       grdView_Form2.Databind();
         }
  }
In the above method the method is static but grdView_Form2 is a non-static field, i guess i will get an error here .. should i remove the static or what ?

The other concern i have is we i defined this method in the Form2_load as you mentioned :
Thread t = new Thread (RefreshDataGrid);    
t.Start();                          

but the thing is my Form2 is not getting loaded again, my need is Form2 is already open .. datasource get changed .... gridvoew should display it.. as we are writing the above method in page load .. it will not called if the datasource is changed because for now Form2 is not loaded again.

Let me know the workaround of above two concerns.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Imperdonato

Yeah, sorry for that... please remove the 'static' from the method definition.

About your second concern, so that;s ok... The purpose for putting this in Form2_Load is to start the thread only once, and it will continue for as long as you like... for that, do the following:
void RefreshDataGrid() {    
     while (true){
    if (Form1.isChanged) {
        grdView_Form2.DataSource = Form1.dataSource;
        grdView_Form2.Databind();
          }
     }
   }

Hope this helps!
annasaru

ASKER
Ok, i modified the code , now i am getting the error like below.. i think its because as i don't know any reference to the grid in the Form1 ... grid is included and populated on just Form2 .... there is no reference to it in the Form1.. in Form1 i am just updating the dictionary object which is the datasource to the grid used in Form2 as i mentioned earlier.
Error :
Cross-thread operation not valid: Control 'dataGridView1' accessed from a thread other than the thread it was created on.

One other error i am gettin is :  when using grdView_Form2.Databind(); itw throwing
'System.Windows.Forms.DataGridView' does not contain a definition for 'Databind' and no extension method 'Databind' accepting a first argument of type 'System.Windows.Forms.DataGridView' could be found (are you missing a using directive or an assembly reference?

Hoping the answer from you.
ASKER CERTIFIED SOLUTION
Imperdonato

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
annasaru

ASKER
Thanks , now i am able to build the solution successfully but unfortunately there is issue which need to be addressed.. i hope you don't mind.
The thing is gridview has a bindingSource(at design mode) as a datasource and inturn this bindingSource has a datasource which is the 'Value' of the dictionary we defined in the Form1 and on Form2 in the constructor i am adding getting the value of the dictionary with Foreach loop and adding the value to bidingSource of the grid. Eg

in Form1
public static Dictionary<long, classA> dList = new Dictionary<long, classA>();

Constructor Form2:
Form2()
{
foreach (KeyValuePair<long, classA > keyValue in Form1.dList)
            {                
               BindingSource.Add(keyValue.Value);                
            }  
} In this way i am populating the datasource of grid(which is bindingSource) with the values of dlist

So in our case i am not sure what i shud do in the loop of below method as right now its showing rowcount of grid as 0 but we do have count=1 in Form1.dataSource.

void RefreshDataGrid() {    
    while (true){
    if (Form1.isChanged) {
       grdView_Form2.DataSource = Form1.dataSource;
         }
    }
  }

Thanks
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
Imperdonato

From the code that you have given, I infer that you are using Form1.dataSource (a static variable in Form1) to put data in grid of Form2 (in the RefreshDataGrid method).

If that is the case, please note that you will need to change/ assign value to this variable (Form1.dataSource) whenever your actual datasource changes (dList in this case?). Else, since dList is already a static dictionary, you can use the same in your RerfreshDataGrid method.

Hope this helps!
annasaru

ASKER
Hi,
I am able to achieve it.. i used one foreach loop in RefreshDataGrid method to assign the values of dlist to bindingSource and then assigned that bindingSource to grid again.

Thanks