Modal Workflow
By "Modal Workflow" we mean the ability to suspend the execution of server-side code, waiting for user input, and to be able to resume the execution flow using any information that may have been received from the user.
It's simple when running a desktop application. It's very hard when running a web application where the code is being executed on the server and the UI is completely asynchronous and running on different machines.

Modal Workflow

The code and images below illustrate how Wisej handles modal execution of code:
C#
VB.NET
void button1_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Are you sure?", buttons: MessageBoxButtons.YesNo) == DialogResult.Yes)
{
this.button1.BackColor = Color.Green;
this.button1.Text = "You selected: Yes!";
}
}
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If MessageBox.Show("Are you sure?", buttons:=MessageBoxButtons.YesNo) = DialogResult.Yes Then
Me.Button1.BackColor = Color.Green
Me.Button1.Text = "You selected: Yes!"
End If
End Sub
Before clicking the button.
After clicking the button.
Now the server code is suspended, waiting for the user to choose. After the user clicks Yes or No on the client-side, the server code will resume exactly where it was suspended.
After the user selected Yes.
Wisej can handle nested modal states, custom dialog results and can reference controls in the modal dialog, as well as any data entered by the user .

Modal Dialogs

Modal workflow works for message boxes and forms (dialog boxes) with any type of control, data binding, and code-behind. The example above, modified to use a modal dialog, looks like this:
C#
VB.NET
void button1_Click(object sender, EventArgs e)
{
using (new dialog = new EnterCustomerAddress())
{
if (dialog.ShowDialog(this) == DialogResult.OK)
{
AlertBox.Show(dialog.textBoxAddress.Text + " " + dialog.textBoxState.Text);
}
}
}
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using dialog As New EnterCustomerAddress()
If dialog.ShowDialog(Me) = DialogResult.OK Then
AlertBox.Show(dialog.textBoxAddress.Text + " " + dialog.textBoxState.Text)
End If
End Using
End Sub
Regular modal dialogs or message boxes suspend the current thread while waiting for user input. By default the system can handle about 32,000 threads. While the thread is suspended it doesn't use any CPU time.

Async Modal Dialogs

Wisej fully supports the async/await programming pattern also for modal dialogs.
Using the await keyword a modal dialog can wait to be closed without suspending the thread. Just use the "Async" version of the ShowDialog method.
The async version of the MessageBox is MessageBox.ShowAsync(...).
C#
VB.NET
void async button1_Click(object sender, EventArgs e)
{
using (new dialog = new EnterCustomerAddress())
{
if (await dialog.ShowDialogAsync(this) == DialogResult.OK)
{
AlertBox.Show(dialog.textBoxAddress.Text + " " + dialog.textBoxState.Text);
}
}
}
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using dialog As New EnterCustomerAddress()
If Await dialog.ShowDialogAsync(Me) = DialogResult.OK Then
AlertBox.Show(dialog.textBoxAddress.Text + " " + dialog.textBoxState.Text)
End If
End Using
End Sub
Asynchronous modal dialogs or message boxes don't use any thread while waiting for the user input.

Custom Modal State

You don't need to use a modal dialog or message box to "go modal" and wait for user input. Wisej provides the Application.DoModal(component) method to let your code go modal at any time.
For example, the PropertyGrid uses the Application.DoModal() to suspend the code flow while waiting for the user to close the drop down selection box. Use Application.EndModal(component, result) to terminate the last modal state: modal states are stacked.
C#
VB.NET
// Open the combo box drop down list and wait
// for the user to select an item or close the combo box.
private void button1_Click(object sender, EventArgs e)
{
this.comboBox1.DroppedDown = true;
this.comboBox1.DropDownClosed += ComboBox1_DropDownClosed;
this.comboBox1.SelectedIndexChanged += ComboBox1_SelectedIndexChanged;
// wait for the user to either pick an item or close the drop down.
var result = Application.DoModal(this.comboBox1);
// code execution will resume here.
}
private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
this.comboBox1.DropDownClosed -= ComboBox1_DropDownClosed;
Application.EndModal(this.comboBox1, DialogResult.OK);
}
private void ComboBox1_DropDownClosed(object sender, EventArgs e)
{
Application.EndModal(this.comboBox1, DialogResult.Cancel);
}
' Open the combo box drop down list And wait
' for the user to select an item Or close the combo box.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.ComboBox1.DroppedDown = True
AddHandler Me.ComboBox1.DropDownClosed, AddressOf ComboBox1_DropDownClosed
AddHandler Me.ComboBox1.SelectedIndexChanged, AddressOf ComboBox1_SelectedIndexChanged
' wait for the user to either pick an item Or close the drop down.
Dim result As DialogResult = Application.DoModal(Me.ComboBox1)
' code execution will resume here.
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs)
RemoveHandler Me.ComboBox1.DropDownClosed, AddressOf ComboBox1_DropDownClosed
Application.EndModal(Me.ComboBox1, DialogResult.OK)
End Sub
Private Sub ComboBox1_DropDownClosed(sender As Object, e As EventArgs)
Application.EndModal(Me.ComboBox1, DialogResult.Cancel)
End Sub
The code snippet above opens a drop down and waits for the user to either select an item or close the combo box. If the user closes it without a selection, DoModal returns DialogResult.Cancel, otherwise it returns DialogResult.OK.
It's quite a powerful way to manage code execution and synchronize it with user actions.
We'll add Application.DoModalAsync(component) in a future build.
Export as PDF
Copy link
On this page
Modal Workflow
Modal Dialogs
Async Modal Dialogs
Custom Modal State