2

Is it possibile to create a modal dialog form following the singleton pattern?

The idea is:

public partial class Singleton : Form
{
    private static Singleton _instance = null;

    private Singleton()
    {
        // Initialization code
    }

    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
                _instance = new Singleton();

            return _instance;
        }
    }

    private void Singleton_FormClosing(object sender, FormClosingEventArgs e)
    {
        _instance.Hide();
        e.Cancel = true;
    }

    private void buttonClose_Click(object sender, EventArgs e)
    {
        this.Close();
    }
}

This code works fine if the form is non-modal (so, if the Show() method is used), but does not work if the form is modal (so, if the ShowDialog() method is used) because this will also hide the parent form.

Cristiano
  • 806
  • 9
  • 24
  • 5
    Why? What problem is that supposed to solve? – Oded Mar 12 '12 at 16:37
  • Why do you think this will hide the parent form? – ionden Mar 12 '12 at 16:41
  • The form has to be a singleton because it needs long time to be initialized, so I want it to be created just once. And I need it to be modal because I need a user answer - yes or no. – Cristiano Mar 12 '12 at 16:41
  • @ionden I implemented this, and (random) the parent form hides. – Cristiano Mar 12 '12 at 16:42
  • 2
    If I could, I'd zap your brain to remove the idea of a singleton from it. It is a very inappropriate pattern to use here. You should not need to provide a buttonClose_Click handler for a dialog, there are several fields you can set up to handle all this for you. I don't think Show/Hide will be significantly faster than Create/Close and it goes against the way the window manager is expecting you to do dialogs. Bad optimisation I think. – Skizz Mar 12 '12 at 16:49
  • In my mind, a singleton form is the wrong way. Why did the form need long time to be initialized? – Viacheslav Smityukh Mar 12 '12 at 16:51
  • @Viacheslav Smityukh: because the form is a custom touch keyboard, created using a custom control for each button. Each button is a base bitmap (the classical keyboard button) where I need to draw the 'symbol' representing the button. The user needs to accept the input or to cancel it. – Cristiano Mar 12 '12 at 16:56
  • 1
    You should separate bitmap creation process from the form initialization. You can use singleton to a images context instead of the whole form. – Viacheslav Smityukh Mar 12 '12 at 17:05

2 Answers2

6

Further to my comment, don't do it this way. Don't make the form/dialog a singleton. The dialog should just present a view of the data you want to show. The caching of the data should be handled elsewhere1. So, when you create the dialog, pass it the cached objects you want it to show. Essentially, use an MVC pattern.

  1. I assume it's data that is taking the time and not the structure of the dialog itself. If the building of the controls on the dialog is taking too long, perhaps the dialog is too complex?
Skizz
  • 67,359
  • 10
  • 66
  • 108
0

I imagine that anything is possible, but: enter image description here

"Just because you can doesn't mean you should."

A singleton has two main purposes: limiting instance count to 1 and providing an entry point for global variables. Whenever you decide to make something a singleton, you're making a very specific and rigid assumption about your domain with which all future developers, yourself included, will be saddled. Namely, you're making the (awkward) assumption that only one X could ever exist. The global nature of singletons will lock you in via inline client calls once you start down this path, and rethinking it later becomes a world of pain.

So, ask yourself this: is there any conceivable way I might ever need to support more than one dialog window? If the answer to this question is or even might be "yes", you don't want to do this as a singleton. If the answer to this question is no, you probably still don't want to do it this way.

Erik Dietrich
  • 5,980
  • 6
  • 23
  • 37