tags:

views:

92

answers:

3

Hi all,

Anyone who's done any UI work in .Net is very familiar with this type of code:

TestForm frm = new TestForm();
frm.ShowDialog();

Earlier today i found myself wishing that a call to show a modal dialog was a little less verbose, more like a static call, and figured out that all i really need, in a simple case, is something like this:

new TestForm().ShowDialog();

Am i missing anything? Could there be any repercussions from this kind of shorthand? E.g. windows messages not handled/routed correctly etc.?

Was working on this when i saw Ray's feedback:

i suppose an even shorter way would be to create a static member withing TestForm that creates an instance of itself and calls ShowDialog internally. So, this code:

public static DialogResult DoModal()
{
    return new TestForm().ShowDialog();
}

could be invoked thusly:

TestForm.DoModal();

Is this what you're talking about Ray? It's static, but does it fit the factory paradigm?

+4  A: 

If you don't want to reuse the form object anywhere in your code you can just use the short form

new TestForm().ShowDialog();

If you want to do something later with that object then you must assign it to a variable.

RaYell
+2  A: 

Pretty simple. Hide form constructor (make it private), then add static factory method that would initialize new instance of the form and show it straight away.

For example see MessageBox source codes (Mono, if I'm not mistaken) link

Ray
i'm not sure why this got a down vote... Please check my edit of the original question. Ray's point seems solid. +1 to get back to 0...
Paul Sasik
Thank you.
Ray
+1  A: 

Typical use of ShowDialog should look like this:

using (Form form = new Form())
{
    // here setup your form instance

    if (DialogResult.OK == form.ShowDialog())
    {
        // here read data from form instance
    }
}

Please be aware that ShowDialog() causes form instance to not dispose itself. You should dispose it manually once you are done with it - hence using clause See http://msdn.microsoft.com/en-us/library/w61zzfwe.aspx for details. In your scenario this should look like below:

public static DialogResult DoModal()
{
    using (Form form = new TestForm())
        return form.ShowDialog();
}

But this is useful only when you don't need to read any data back from your form instance. So the only scenario that fits here is message box. MessageBox.Show(...) methods utilize pattern you want to implement in your post.

in other scenarios forms are supposed to return data other than DialogResult back to application after they are closed. And that's why standard Form does not have static ShowDialog() or DoModal() methods. Static method should dispose temporal form instance. Such disposal would make impossible to read data back from form. What is more, in static method scenario there is no form instance to read data back from.

Putting all together, your method, to be compliant with guidelines, should look more like:

public static YourResultClass DoModal()
{
    using (TestForm form = new TestForm())
    if (DislogResult.OK == form.ShowDialog())
    {
        YourResultClass result = new YourResultClass();
        // Here initialize YourResultClass instance with data from form instance
        return result;
    }
}

But that is very use case specific and quite far from your one-liner utility method.

Przemaas
That's an interesting notion Przemaas. But could you share some documentation/links to back it up? From my understanding the form, or any object for that matter, declared at function scope should get GCed at some point after the the function is taken off the stack. Very few objects such as Graphics actually need Dispose called from client code.
Paul Sasik
Here is some MSDN reading: http://msdn.microsoft.com/en-us/library/w61zzfwe.aspx
Przemaas
yes, it will be GC-ed, but after second garbage collection. First garbage collection will only call Dispose(). So calling Dispose() manually is recommended practice because it speeds up resources cleaning. This is true for all IDisposable objects, not only forms. Not disposing such objects can lead to potential leaks and performance problems, especially when such objects allocate unmanaged resources. Each alive form (and control too) needs to allocate window handle to exist. So single form can allocate many window handles. Windows handles are not managed objects and are not cheap.
Przemaas
Here is link to Garbage Collection in MSDN: http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx
Przemaas
Here is link to Maoni's blog on .Net GC: http://blogs.msdn.com/maoni/
Przemaas
Here is link to Tess' blog on debugging .Net applications: http://blogs.msdn.com/tess/default.aspx You can find there plenty of posts about how not disposing objects can lead to leaks, hang or crash of app and how to troubleshoot such problems.
Przemaas
Przemaas, +1 for the great writeup on .Net internals. But i had to award the answer elsewhere since yours a bit off the original question. You should blog your discussion above!
Paul Sasik
Just remembered, CodeProject would be a good place for an article like this...
Paul Sasik