I am using modal windows to input data but I can’t find a way to communicate the data back to the main window. I put properties in a module, in the main window, in the app but nothing seems to work. Is anyone else having this problem and can anyone tell me how to communicate between my dialogs and my main code?
Create a property in your modal window to hold the value you need to return.
Create a method in that window which returns a value of that type
In that method, deal with any arguments that need to be passed, then call
From your main screen, call that method
myReturnedVal = myModalWin.myMethod(arg)
be sure to set the value of the property to be returned in your modal window before calling self.Close and the value will be return to your calling screen.
How you choose to design it depends on the task at hand. If you’re dealing with an isolated task you probably don’t want to be setting global variables.
Here’s a three-step approach.
- Main Window (winMain) opens your dialog
- When the task is completed and the user presses the OK button, winDialog passes dictionary of values back to the Main Window
winDialog : btnOK : Action:
[code]dim d as new Dictionary
winMain.DialogProcessDone( d )
- winMain handles the values passed from the dialog,
[code]sub DialogProcessDone( d as dictionary )
if d.HasKey(“Key1”) then
// do something with d.Value(“Key1”)
if d.HasKey(“Key2”) then
// do something with d.Value(“Key2”)
The problem with that approach is in the Modal Window calling the main window. Firstly, what if you want to call this dialog from another window than winMain? Secondly, with implicit instantiation, calling winMain by name will cause it to show. That CAN lead to hard to find bugs. I think it much better to allow winMain to do all of the calling and the modal window to just return a value.
My goal was a simple non-blocking model for a limited use case. (Where we know that only winMain will be calling winDialog)
For a multi-purpose approach it would be better to create a class which encapsulates the dialog’s functions and fires an event when the dialog is finished. One would then add the class to their window and handle the events as needed without the blocking problems pursuant to using window.ShowModal
What about using events? For example, your dialog may have 3 possible outcomes, OK, Cancel or Alternative… Thus, define those 3 items as an Event in your dialog with the parameters that you want to pass to your main window, then in your main window:
[code]Dim myDlg As New MyDialog
AddHandler myDlg.OK, AddressOf UserPressedOK
AddHandler myDlg.Alternative, AddressOf UserPressedAlt
’ Maybe we don’t care about cancel, so we don’t add a handler for it.
So, your UserPressedOK method may look like:
Sub OkButtonPressed(w As MyDialog, username As String, password As String, rememberMe As Boolean)
' Do something with the data here
Using this method, your main window can even communicate back to your dialog, for example, your handler method could return a True if the data was acceptable or False if not:
[code]Function OkButtonPressed(w As MyDialog, username As String, password As String, rememberMe As Boolean)
Dim u As User = LoadUser(username, password)
If Not u.IsValid Then
Edit: Hm, should have read more of Thomas’s response, he suggested using events as above as a more complete method.
Another way is to use a delegate