tags:

views:

68

answers:

5

In my C# application I have an option dialog that can be opened from a menu command.

I want to ensure that the option dialog have only one instance (user cannot open more than one option window at a given time) without making it modal.

Also if the user already have this window opened, and he clicks in the menu item to open it again, the app just makes the already visible form became the top most window.

Can anyone point me directions on how accomplish these tasks?

Thank you very much.

+4  A: 

Well, the simplest way is to have a static field which stores a reference to the single instance or null, and then a method to retrieve it or create a new one.

Note that this isn't the same as making it a singleton - because I assume if the form is closed, you'd want to create a new instance next time. (The alternative - hiding it and reusing it - is shown in STO's answer.) You may want something like this:

public class OptionsDialog : Form
{
    private static OptionsDialog openForm = null;

    // No need for locking - you'll be doing all this on the UI thread...
    public static OptionsDialog GetInstance() 
    {
        if (openForm == null)
        {
            openForm = new OptionsDialog();
            openForm.FormClosed += delegate { openForm = null; };
        }
        return openForm;
    }
}

You may want to make the method perform the "bring it to the front" steps as well, of course.

Jon Skeet
Hi @Jon, can you provide an example, please?
RHaguiuda
@RHaguiuda: What do you want other than the code I've given?
Jon Skeet
Hmm, I can see where that request came from, that's not what the post looked like originally. Fastest gun in the West trick?
Hans Passant
Yeah, when I posted the comment, there was no code in the post. Weird!
RHaguiuda
@RHaguiuda: There's been code there for quite a long time... it may not have had code when you *loaded* the page, but I'm sure it did before you posted the comment. No matter though ;)
Jon Skeet
Anyway... @Jon thank you very much for helping.
RHaguiuda
+1  A: 

you may use code like this:

private MyDialogForm _FormInstance;

public void ShowOptions()
{
     if (_FormInstance == null)
     {
        _FormInstance = new MyDialogForm();
        _FormInstance.FormClosing += (s,e) => 
        {
             e.Cancel = true;
             _FormInstance.Hide();
        }
      }
     _FormInstance.Show();
}
STO
+1  A: 

You will need this form as property

Form1 myForm = null;
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    myForm = null;
}

private void ShowForm()
{
    if (myForm != null)
    {
        myForm.BringToFront();
    }
    else
    {
        myForm = new Form1;
        myForm.Show();
    }
}
volody
Just declare myForm as static to be accessible by my options form FormClosed event (to make myForm = null again).
RHaguiuda
A: 

I assume you have at least two forms. One form, call it frmMain, allows you to open frmOptions. In frmMain, add a variable of type frmOptions like this:

public partial class frmMain : Form
{
     private frmOptions optionsInstance = null;
     ...

In the routine that opens the Options dialog, add this:

if (optionsInstance == null || !optionsInstance.Visible)
{
     optionsInstance = new frmOptions();
     optionsInstance.Show();
}

When frmOptions closes, optionsInstance will not be null, so that's why you check if it's visible before instantiating a frmOptions instance.

If this doesn't work for you, you could try a mutex, but that's probably overkill.

SimpleCoder
+1  A: 

You need to prevent the form from closing. If you don't, the form will be disposed and becomes unusable. You can do this by implementing the FormClosing event:

    protected override void OnFormClosing(FormClosingEventArgs e) {
        if (e.CloseReason == CloseReason.UserClosing) {
            this.Hide();
            e.Cancel = true;
        }
    }

To make it a singleton, just keep track of the life time of the form in your main form class:

    frmOptions options;

    private void btnShowOptions_Click(object sender, EventArgs e) {
        if (options == null) {
            options = new frmOptions();
            // To make absolutely sure:
            options.FormClosed += (o, ea) => options = null;
        }
        else {
            options.WindowState = FormWindowState.Normal;
        }
        options.Show();
    }
Hans Passant