Remotely firing a public sub/function from within a Windows Form?

Here is a scenario within my Windows application.

I have a Form (Form 1) open that contains many ComboBoxes. Each of these CB's contain system data or "Lookup" data. This "Lookup" data is dynamically controlled from another form (Form 2) that only certain users with special permissions can access.

What I need to be able to happen is that when Form 1 is open and the user realizes that a particular CB needs a data element added to it, they can open Form 2, add a new data element to whichever "Lookup" table they need and then save the data and close the form. On Form 1, I have a Button that is disable for most of the time. This Button needs to be enabled and when clicked will update one or more CB's. What I need is for a way to "Enable" this Button once Form 2 has saved data.

Can I declare a Public Event somewhere? If so, where should it be declared? I'm not sure how to automatically enable the Button when this scenario happens, which should be very rare!!!

Thanks!
BlakeMcKennaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jacques Bourgeois (James Burger)PresidentCommented:
Instead of using Show to display Form2, use ShowDialog. This freezes the code in Form1, until Form2 is closed or made invisible. Then the code continue. Thus, the following, running in Form1, will do the job:

Form2.ShowDialog
YourButton.Enabled=True

One other advantage or working that way, that can be a disadvantage in some situations, is that when Form2 is used that way, users cannot come back to Form1 until Form2 is closed. They thus have to finish the job in Form2 before coming back to Form1. This is the same mechanism that is used by the About box in most applications.
0
BlakeMcKennaAuthor Commented:
James,

I'm not so sure this option would work. The Form 2 is opened by using a Function Key or a Main Menu option. The way I'm envisioning this is that when the "Save" button is clicked on Form 2 (assuming data was added to a "Lookup" table), it would raise an event that resides in a public module or within Form 1 that would enable the Button in Form 1.
0
it_saigeDeveloperCommented:
You are on the right track with regards to events (although Jacques does provide a valid point).  Here is a small event based example:

Form1.vb -
Public Class Form1
	Dim form2 As Form2 = Nothing

	Private Sub OnLoad(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
		btnUpdate.Enabled = False
	End Sub

	Private Sub OnClick(ByVal sender As Object, ByVal e As EventArgs) Handles btnUpdate.Click, btnOpen.Click
		If TypeOf sender Is Button Then
			Dim btn As Button = DirectCast(sender, Button)
			If btn.Equals(btnOpen) Then
				If form2 IsNot Nothing Then
					RemoveHandler form2.Updated, AddressOf OnForm2Updated
					form2.Dispose()
					form2 = Nothing
				End If

				If form2 Is Nothing Then
					form2 = New Form2()
					AddHandler form2.Updated, AddressOf OnForm2Updated
					AddHandler form2.FormClosed, AddressOf OnForm2Closed
					form2.Show()
				End If
			End If

			If btn.Equals(btnUpdate) Then

			End If
		End If
	End Sub

	Private Sub OnForm2Updated(ByVal sender As Object, ByVal e As EventArgs)
		btnUpdate.Enabled = True
	End Sub

	Private Sub OnForm2Closed(ByVal sender As Object, ByVal e As EventArgs)
		btnUpdate.Enabled = False
	End Sub
End Class

Open in new window

Form1.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
		Me.btnOpen = New System.Windows.Forms.Button()
		Me.btnUpdate = New System.Windows.Forms.Button()
		Me.SuspendLayout()
		'
		'btnOpen
		'
		Me.btnOpen.Location = New System.Drawing.Point(13, 13)
		Me.btnOpen.Name = "btnOpen"
		Me.btnOpen.Size = New System.Drawing.Size(101, 23)
		Me.btnOpen.TabIndex = 0
		Me.btnOpen.Text = "Open Form 2"
		Me.btnOpen.UseVisualStyleBackColor = True
		'
		'btnUpdate
		'
		Me.btnUpdate.Location = New System.Drawing.Point(171, 12)
		Me.btnUpdate.Name = "btnUpdate"
		Me.btnUpdate.Size = New System.Drawing.Size(101, 23)
		Me.btnUpdate.TabIndex = 1
		Me.btnUpdate.Text = "Form 2 Updated"
		Me.btnUpdate.UseVisualStyleBackColor = True
		'
		'Form1
		'
		Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
		Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
		Me.ClientSize = New System.Drawing.Size(284, 49)
		Me.Controls.Add(Me.btnUpdate)
		Me.Controls.Add(Me.btnOpen)
		Me.Name = "Form1"
		Me.Text = "Form1"
		Me.ResumeLayout(False)

	End Sub
	Friend WithEvents btnOpen As System.Windows.Forms.Button
	Friend WithEvents btnUpdate As System.Windows.Forms.Button

End Class

Open in new window

Form2.vb -
Public Class Form2
	Private ReadOnly fUpdatedHandlers As New List(Of FormUpdatedEventHandler)
	Public Custom Event Updated As FormUpdatedEventHandler
		AddHandler(ByVal value As FormUpdatedEventHandler)
			fUpdatedHandlers.Add(value)
		End AddHandler

		RemoveHandler(ByVal value As FormUpdatedEventHandler)
			fUpdatedHandlers.Remove(value)
		End RemoveHandler

		RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
			For Each handler As FormUpdatedEventHandler In fUpdatedHandlers
				Try
					handler.Invoke(sender, e)
				Catch ex As Exception
					Debug.WriteLine(String.Format("Exception reported while invoking event handler: {0}", ex))
				End Try
			Next
		End RaiseEvent
	End Event

	Protected Overridable Sub OnUpdated(ByVal sender As Object, ByVal e As EventArgs)
		RaiseEvent Updated(sender, e)
	End Sub

	Private Sub OnClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSimulate.Click
		OnUpdated(Me, EventArgs.Empty)
	End Sub
End Class

Public Delegate Sub FormUpdatedEventHandler(ByVal sender As Object, ByVal e As EventArgs)

Open in new window

Form2.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form2
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
		Me.btnSimulate = New System.Windows.Forms.Button()
		Me.SuspendLayout()
		'
		'btnSimulate
		'
		Me.btnSimulate.Location = New System.Drawing.Point(75, 26)
		Me.btnSimulate.Name = "btnSimulate"
		Me.btnSimulate.Size = New System.Drawing.Size(134, 23)
		Me.btnSimulate.TabIndex = 1
		Me.btnSimulate.Text = "Simulate Save Event"
		Me.btnSimulate.UseVisualStyleBackColor = True
		'
		'Form2
		'
		Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
		Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
		Me.ClientSize = New System.Drawing.Size(284, 75)
		Me.Controls.Add(Me.btnSimulate)
		Me.Name = "Form2"
		Me.Text = "Form2"
		Me.ResumeLayout(False)

	End Sub
	Friend WithEvents btnSimulate As System.Windows.Forms.Button
End Class

Open in new window

Produces the following output -Initial Run.After pressing the Open Form 2 Button.After pressing the Simulate Save Event Button on Form2.After closing Form 2.-saige-
0
Jacques Bourgeois (James Burger)PresidentCommented:
OK. More details, you seem to have a condition to check in Form2 before enabling the button. The event seems to be the most appropriate way to go for that and is quite easy to implement.

In Form2, add the following to the Declarations section of the form.

    Public Event YourEvent(sender As Object, e As EventArgs)

When you close Form2 after having checked that data was added, trigger the event with the following code.

     RaiseEvent YourEvent(Me, New EventArgs)

In Form1, to catch that event, create a procedure with the proper signature (parameters). The name of the procedure is not important, it's the signature that is.

     Public Sub YourProcedure (sender As Object, e As EventArgs)
          YourButton.Enabled=True
          RemoveHandler YourForm2.YourEvent, AddressOf YourProcedure
     End Sub

To register that procedure for the event, add the following code just before displaying Form2

      AddHandler YourForm2.YourEvent, AddressOf YourProcedure
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BlakeMcKennaAuthor Commented:
James,

That worked perfectly. I definitely learned something new!

Thanks!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.