Link to home
Start Free TrialLog in
Avatar of rgn2121
rgn2121Flag for United States of America

asked on

WinForms - Invoking events on one form from another form

I have an app that opens a form that contains a CR Viewer control. I have added a button so that when you click the button on the (reportForm) it fires the click event in the mainform and starts a download for data.  This way I can refresh the data without closing and reopening the form.

The problem is that when I click the "refresh" button on the reportForm, it fires on the main form, is caught, but it seems to run through the code 2 times...like I clicked the main download button twice.  That really isn't possible since the main button is disabled as soon as it is clicked, but I know it runs 2 times because the thread that does the download, its thread_complete code runs 2 times causing me errors.

in the main form I have declared a ToolStripButton, since that is what is used on the reportForm, as the following:
Private WithEvents refreshDataButton as ToolStripButton

Then when the reportForm is created, I "link" the buttons...
dim viewer as new reportForm
refreshDataButton = viewer.reportRefreshButton
viewer.Show()

I then catch the click event of the refreshDataButton in the mainform, but the code that runs gets ran 2 times...I will post more code if needed...

Any help is appreciated...
Avatar of rgn2121
rgn2121
Flag of United States of America image

ASKER

Okay...I think I might know what it is, but I am not sure how to get around it.  When the download is finished, I raise an event in the main form RefreshDataCompleted.  to catch this event I declare an instance of my main form in the report form:
private tempMainForm as new mainform
This way I can handle the event tempMainForm.RefreshDataCompleted.  This is what causes me issues though, or so I guess, by me declaring and intializing the mainform in the reportform, when button clicks happen it happens in both, even though I can only visibly see one.  I see it hitt he thread_Completed in Debug, because it hits that event twice?
Not sure if this is confusing or makes since, but that is where I am at... I tested this by adding another declaration of main form to the report form and it hit my thread completed an extra time.  So it hits once for my main form and then once for each instance I have declared.
 
Avatar of rgn2121

ASKER

Maybe this is because when I open my main Form I just do mainForm.show() instead of
dim myMain as New mainForm
myMain.show()
???
ASKER CERTIFIED SOLUTION
Avatar of Muhammad Ousama Ghazali
Muhammad Ousama Ghazali
Flag of Saudi Arabia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of rgn2121

ASKER

Nope...still hits it 2 times
Avatar of rgn2121

ASKER

Thanks for the reply..
I have no code behind the viewer.reportRefreshButton.Click event other than
reportRefreshButton.Enabled=False
As to your questions...
1.  The mainForm loads and the user can click a button.  This button starts a download from Oracle Tables.  The data is downloaded, interpreted, and prepared for reporting.  When the user wants to view reports, then click a button that loads the reportForm.  Before the .Show() of this form I do the following.
dim viewer as New reportForm
viewer.RptData = TempDS
refreshReportViewerButton = viewer.refreshReportDataButton
viewer.Show()
This way the report Form has the DataSet and the ToolStripButton in the mainForm is linked to the ToolStripButton that users will click on the reportForm to refresh the data.
I am not sure I follow for 2 and 3...
Avatar of rgn2121

ASKER

My download routine in the mainForm does a couple checks and then calls code from different DLL's to do the downloading and Interpreting.  If I was to call this from the report Form I would be duplicating a lot of code, unless I can call the method in the mainForm that starts the checking and downloading directly?
Not sure how to call a Sub in another form...
Avatar of rgn2121

ASKER

Okay...I was right about what was causing it...now I need to figure out how to fix it...  
I commented out the declarations of mainForm in my reportForm and everything ran as it should.  now I just need to know how to let the reportForm know that the new data is ready...
 
Avatar of rgn2121

ASKER

I think I got what you were suggesting...maybe not, but I created a method in the reportForm and I call it from the mainForm when the refresh is completed.
This seems to work just as I expected the other to work without creating all the instance of my mainForm...  Is this what you were talking about or did I miss something along the way?

Friend Sub UpdateUIControls()
'code
End Sub

Open in new window

Avatar of rgn2121

ASKER

One final point...I just read an article that said to create a Class that contains all of your forms as shared forms.  Once you have them all declared it tells you to setup your references when you actually create the form in code.
I pasted the samples below...I am curious what your thoughts on this is..?

Public Class myFormLibrary
    Public Shared Form1 As Form
    Public Shared myUserForm1 As Form
    Public Shared myUserForm2 As Form
End Class
 
Private Sub Form1_Load( _
	ByVal sender As System.Object, _
	ByVal e As System.EventArgs) _
	Handles MyBase.Load
    myFormLibrary.Form1 = Me
End Sub

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You need to create a new Module in your project and may name it anything but the example above assumes it GlobalRoutines.vb. Further, mistakenly the name for the routine is wrongly written as DownloadData(), instead it should be GetReportData().
Hope it will help you.
Avatar of rgn2121

ASKER

I appreciate the code, but I have already created dll's that do all this for me on multiple threads.  All that works flawlessly and I can download and process 10's of thousands of records in seconds.  I do something very similar to what you suggest, but just by creating the reference between to buttons, I have gotten what I needed.
The mainform shows it's put clicked, the DataGridView refreshes it's data, the report form shows it's controls refresh and the data is available without the references to other forms.
I am curious what you think about the idea of a Forms Library though...I will award points for you code and suggestions.  Thank you...
It is always better to have Library for your code that you wish to share accross multiple projects and teams whether it be Forms, Controls, Components, DataAccess Routines, or simply some Code-based routines.
Maybe it is that I could not get the full imagination of what you wished to acheive, but it is good that you figured out something.