0

How would you make an instance of a form open itself in a Modal way?

I tried this.ShowDialog() but it doesn't make the form appear modal (you can still access other forms). I guess this is because it is it's own parent form in if it shows itself, but I'm not sure.

My problem:

I have an application made of 2 forms:

  1. MainForm
  2. LoginForm

MainForm creates an instance of and opens LoginForm to ask the user to authenticate. LoginForm has a timer to regularly check and log the user in - I want this timer to open LoginForm modally. I know this could be achieved by putting the timer in MainForm but I would like to know how to make a form ShowDialog() an instance of itself.

Thanks in advance.

9
  • 1
    From my experience ShowDialog does not let you access other forms... Commented Jul 12, 2012 at 10:21
  • 1
    Can you show how are you doing this ? What do you do in Application.Run then ? Commented Jul 12, 2012 at 10:26
  • Why would you call ShowDialog inside form, which you want to show? Commented Jul 12, 2012 at 10:34
  • After user logins, your LoginForm will be destroyed. Where you suppose timer will run? Commented Jul 12, 2012 at 10:40
  • @Shai That's the idea, I effectively want to be able to change the read only property this.Modal to true to prevent access to other forms. Commented Jul 12, 2012 at 10:40

3 Answers 3

2

Make sure you call ShowDialog after InitializeComponent:

public newForm()
{
    InitializeComponent();
    this.ShowDialog();
}

MY TEST

I made new class named Form2:

public partial class Form2 : Form
{
    public Form2()
    {
        //this may not call in constractor 
        //InitializeComponent();
    }

    public void ShowModalForm()
    {
        InitializeComponent();
        ShowDialog();
    }
}

and start it on main without any parent and it starts modally:

static class Program
{
    [STAThread]
    static void Main()
    {
        new Form2().ShowModalForm();
        //Application.Run(new Form1());
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Hi, I was calling ShowDialog() after InitializeComponent() and it still only effectively Show()s the form.
That works, super. Just realised my problem was probably down to the ShowDialog() being in a new thread feeling dumb. Thanks
1

Form won't be modal if it's a top-level window (has no parent). On the other hand, if your form will have other form as a parent, then it will open modally (blocking parent) on .ShowDialog().

1 Comment

The form LoginForm does have a parent, it's not top level.
0

Here is option for you - define LoginExpired event on your LoginForm. Raise this event on timer tick event handler:

public partial class LoginForm : Form
{
    public event EventHandler LoginExpired;

    public LoginForm()
    {
        InitializeComponent();
        timer.Start();
    }

    private void timer_Tick(object sender, EventArgs e)
    {
        OnLoginExpired();
    }

    protected virtual void OnLoginExpired()
    {
        if (Visible)
            return; // if this form visible, then user didn't authenticate yet

        if (LoginExpired != null)
            LoginExpired(this, EventArgs.Empty);
    }        
}

Then subscribe on this event on your Main method:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    using (LoginForm loginForm = new LoginForm())
    {
        if (loginForm.ShowDialog() != DialogResult.OK)
            return;

        loginForm.LoginExpired += new EventHandler(loginForm_LoginExpired);
        Application.Run(new MainForm());
    }
}

static void loginForm_LoginExpired(object sender, EventArgs e)
{
    LoginForm loginForm = (LoginForm)sender;
    if (loginForm.ShowDialog() != DialogResult.OK)
        throw new NotAuthenticatedException();
} 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.