Cyril Gandon
Cyril Gandon

Reputation: 17068

Modeless Form calling Modal Form is blocking initial Form

I start with a form A.
The form A call a form B with .Show().

So form A and form B are both accessible.

Now, I wan't form B calling form C with ShowDialog(), because I don't want form B be accessible while form C is open.

The problem is : form A is inaccessible.

In this scenario, how can I have both form A and form C accessible, but not form B?

Upvotes: 0

Views: 1058

Answers (2)

Hans Passant
Hans Passant

Reputation: 942267

This is entirely by design, a dialog disables all windows in an application. There's a good reason for that, outlined in this answer.

In brief, the Drastic Failure scenario is that a user could use a command in form A that creates another instance of form B, one that isn't disabled. Which allows you to display C again, now you have two dialogs showing.

You may well sputter that this can never happen in your case. That's okay but you'll then have to undo what ShowDialog() does. Which requires gymnastics, you have to pinvoke EnableWindow() to re-enable the form A instance. But you have to do so after the ShowDialog() call but before it ends. Something you can do by using Control.BeginInvoke() on the UI thread. The trickorama looks like this:

    private void ShowDialogButton_Click(object sender, EventArgs e) {
        using (var dlg = new Form3()) {
            // Find the main form instance
            var main = Application.OpenForms.OfType<Form1>().Single();
            this.BeginInvoke(new Action(() => {
                EnableWindow(main.Handle, true);
            }));
            if (dlg.ShowDialog(this) == DialogResult.OK) {
                // etc..
            }
        }
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool EnableWindow(IntPtr handle, bool enable);

You can also put the EnableWindow() call in the dialog's Shown event handler, that avoids having to use the BeginInvoke trick. But this way is more universal, dialogs should in general not be in the business of knowing what other windows run in an app. The use of Form1 in this code is ugly enough as-is.

Upvotes: 3

Nikola Radosavljević
Nikola Radosavljević

Reputation: 6911

Modal windows are such that they require users input and dismissal before allowing her to return to other part of applications. As such, you can't use them if you want to enable user to interact with more than one window.

You will have to manually handle this situation by disabling window B (setting Enabled to false) before showing window C, and enabling it back again once window C is dismissed.

Upvotes: 0

Related Questions