<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David's Blog &#187; winforms</title>
	<atom:link href="http://craz.net/blog/tag/winforms/feed/" rel="self" type="application/rss+xml" />
	<link>http://craz.net/blog</link>
	<description>The blog of David Hammerton</description>
	<lastBuildDate>Tue, 08 Sep 2009 03:38:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A Generic Singleton Form Provider for C#</title>
		<link>http://craz.net/blog/2008/06/19/a-generic-singleton-form-provider-for-c/</link>
		<comments>http://craz.net/blog/2008/06/19/a-generic-singleton-form-provider-for-c/#comments</comments>
		<pubDate>Wed, 18 Jun 2008 23:54:08 +0000</pubDate>
		<dc:creator>David Hammerton</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[winforms]]></category>

		<guid isPermaLink="false">http://craz.new.eco-shout.org/blog/?p=5</guid>
		<description><![CDATA[An interesting, although generally basic, problem with Windows Forms is how to implement the singleton pattern on the forms. What do I mean? Well, consider this&#8230;
You&#8217;re writing a Windows Forms application and you have a bunch of Forms, such as a Preference window, an About window and so on. You&#8217;d like these forms to be [...]]]></description>
			<content:encoded><![CDATA[<p>An interesting, although generally basic, problem with Windows Forms is how to implement the <a href="http://en.wikipedia.org/wiki/Singleton_pattern">singleton pattern</a> on the forms. What do I mean? Well, consider this&#8230;</p>
<p>You&#8217;re writing a Windows Forms application and you have a bunch of Forms, such as a Preference window, an About window and so on. You&#8217;d like these forms to be modeless, yet you don&#8217;t want the user to be able to create more than one of them.</p>
<p>It&#8217;s a common problem, but there&#8217;s no built in way to handle it. Moreover, I&#8217;ve yet to see an elegant solution to it. The method explained below, which is as elegant as it&#8217;s going to get, creates a pseudo-factory class to manage the problem for you. Read on to find out more.</p>
<p><span id="more-5"></span></p>
<p>If a Form were just any old object, you could implement the Singleton pattern in the said class:</p>
<pre name="code" class="c-sharp">
class SomeSingletonClass {
    protected SomeSingletonClass () {
    }

    private static SomeSingletonClass mInstance = null;

    public static SomeSingletonClass Instance {
        get {
            if (mInstance == null) mInstance = new SomeSingletonClass();
            return mInstance;
        }
    }
}
</pre>
<p>Of course, this isn&#8217;t thread safe &#8211; there are much better ways to do this in the general case. See <a href="http://www.yoda.arachsys.com/csharp/singleton.html">here</a> for a good explanation. In the case of forms, however, we don&#8217;t need to be thread safe. Windows forms are explicitly un-threadsafe themselves. They should (in most cases) only ever be initialized/used from a single thread. This constraint applies here too.</p>
<p>Now, this won&#8217;t work for Windows Forms. How come? Well, once the Windows Form has been closed (with Close() or otherwise) it, generally, gets disposed. We all know you can&#8217;t use a disposed form again. You&#8217;ll get a crash when trying to access the form again. So, what&#8217;s the work around?</p>
<p>Basically, we need to handle the <strong>FormClosed</strong> event, so that we know the form has been closed. We can then remove the reference to the form, once its been closed, and start all over again next time it&#8217;s needed. So we&#8217;d end up with something like this:</p>
<pre name="code" class="c-sharp">
class SomeSingletonForm : Form {
    protected SomeSingletonForm () {
    }

    private static SomeSingletonForm mInstance = null;

    public static SomeSingletonForm Instance {
        get {
            if (mInstance == null)
            {
                mInstance = new SomeSingletonClass();
                mInstance.FormClosed += new FormEventHandler(remover);
            }
            /* Could call mInstance.Show(); */
            return mInstance;
        }
    }

    static void remover(object sender, FormClosedEventArgs e)
    {
        mInstance.FormClosed -= new FormClosedEventHandler(remover);
        mInstance = null;
    }
}
</pre>
<p>Now we&#8217;re getting closer. It seems unnecessary, however, to implement this on every single form that we want to be a singleton form: It&#8217;s a lot of copying identical code, and it&#8217;s prone to bugs.</p>
<p>So what can we do? We create a provider class which creates singleton forms for us. Sort of like a singleton factory with a few little tricks to ensure only valid forms are around. I&#8217;ve seen code before for this on various blogs / message boards, but none of them are as complete as this one.</p>
<p>What&#8217;s the difference? It&#8217;s the use of generics that makes this implementation really handy. By using a generic method, we can return a form of the correct type: there&#8217;s no need to worry about casting.</p>
<p>Another modification is the addition of a parameters to the GetInstance method. Although this is a little dodge, and could break things if you aren&#8217;t careful, I&#8217;ve found it handy when used with a form whose constructor required extra arguments.</p>
<p>So here it is:</p>
<pre name="code" class="c-sharp">
    class SingletonFormProvider
    {
        static Dictionary&lt;Type, Form&gt; mTypeFormLookup = new Dictionary&lt;Type, Form&gt;();

        static public T GetInstance&lt;T&gt;(Form owner)
            where T : Form
        {
            return GetInstance&lt;T&gt;(owner, null);
        }

        static public T GetInstance&lt;T&gt;(Form owner, params object[] args)
            where T : Form
        {
            if (!mTypeFormLookup.ContainsKey(typeof(T)))
            {
                Form f = (Form)Activator.CreateInstance(typeof(T), args);
                mTypeFormLookup.Add(typeof(T), f);
                f.Owner = owner;
                f.FormClosed += new FormClosedEventHandler(remover);
            }
            return (T)mTypeFormLookup[typeof(T)];
        }

        static void remover(object sender, FormClosedEventArgs e)
        {
            Form f = sender as Form;
            if (f == null) return;

            f.FormClosed -= new FormClosedEventHandler(remover);
            mTypeFormLookup.Remove(f.GetType());
        }
    }
</pre>
<p>and to use it:</p>
<pre name="code" class="c-sharp">
AboutBox abox = SingletonFormProvider.GetInstance&lt;AboutBox&gt;(this);
abox.Show();
</pre>
<p>Well, there you have it. A handy Generic Singleton Form provider for C#.</p>
]]></content:encoded>
			<wfw:commentRss>http://craz.net/blog/2008/06/19/a-generic-singleton-form-provider-for-c/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
