Results 1 to 1 of 1

Thread: [2005] Generic Singleton Form (Maintaining Only One Instance of a Form)

  1. #1

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    [2005] Generic Singleton Form (Maintaining Only One Instance of a Form)

    C# version here, courtesy of ForumAccount.

    Often times you want to ensure that you only have one instance of a particular type of form. This is probably most common with MDI child forms, where you only want to have one instance of a child form even if the user tries to open it more than once from a button or menu item. I've often advised people to implement the Singleton pattern for that form but it's a bit cumbersome doing that every time. I always though generics should be able to help but never looked into it any further. I needed this feature myself just recently so I did look further and here's what i cam up with:
    VB.NET Code:
    1. Public Class FormSingleton(Of TForm As {Form, New})
    2.  
    3.     Private Shared _instance As TForm
    4.  
    5.     Public Shared ReadOnly Property Form() As TForm
    6.         Get
    7.             If _instance Is Nothing OrElse _instance.IsDisposed Then
    8.                 _instance = New TForm
    9.             End If
    10.  
    11.             Return _instance
    12.         End Get
    13.     End Property
    14.  
    15.     Public Shared Sub Show()
    16.         'Ensure the form is visible and has focus.
    17.         With Form
    18.             .Show()
    19.             .Activate()
    20.         End With
    21.     End Sub
    22.  
    23. End Class
    This is the interesting part here:
    Code:
    Public Class FormSingleton(Of TForm As {Form, New})
    Many people will have used generics before but may not have declared their own. The underlined part is what makes the class generic. You specify a type for the TForm parameter when you create an instance and everywhere TForm appears in the code is then "replaced" with that type. For instance, if you do this:
    VB.NET Code:
    1. Dim f1 As New FormSingleton(Of Form1)
    that fixes the _form variable and Form property to type Form1.

    The part that is probably unfamiliar to almost everyone is the bold bit. You can constrain generic parameters to allow yourself to treat them in certain ways within the code. For instance, I've specified that TForm must be type Form or a type derived from Form. That allows me to access members of the Form class, e.g. IsDisposed, within that code via a variable of type TForm. That's because we're guaranteed that no matter what type it is those members will be present.

    I've also added a New constraint, which means that the type must have an accessible constructor with no arguments. That's what allows me to create an instance inside the Form property getter. Without that constraint I would not be guaranteed of being able to create an instance like that so the compiler wouldn't let me.

    Now, how do you use it? All you need is one line of code:
    VB.NET Code:
    1. FormSingleton(Of MyForm).Show()
    where MyForm is the type of form you want to display. That will create an instance of MyForm class if one doesn't already exist, then display and focus the one instance of the class. You can just call that one line of code over and over and you'll never get a second instance. If an instance already exists it will simply take focus.

    If you want to use this for MDI child forms you have set the MdiParent property of the class's Form property too, or you could extend the class like this:
    VB.NET Code:
    1. Public Class MdiFormSingleton(Of TForm As {Form, New})
    2.     Inherits FormSingleton(Of TForm)
    3.  
    4.     Public Shared Sub ShowChild(ByVal mdiParent As Form)
    5.         With Form
    6.             .MdiParent = mdiParent
    7.             .Show()
    8.             .Activate()
    9.         End With
    10.     End Sub
    11.  
    12. End Class
    Now your code to show the form becomes:
    VB.NET Code:
    1. MdiFormSingleton(Of MyForm).ShowChild(Me)
    Last edited by jmcilhinney; May 27th, 2009 at 10:02 PM.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width