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:This is the interesting part here:VB.NET Code:
Public Class FormSingleton(Of TForm As {Form, New}) Private Shared _instance As TForm Public Shared ReadOnly Property Form() As TForm Get If _instance Is Nothing OrElse _instance.IsDisposed Then _instance = New TForm End If Return _instance End Get End Property Public Shared Sub Show() 'Ensure the form is visible and has focus. With Form .Show() .Activate() End With End Sub End ClassMany 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:Code:Public Class FormSingleton(Of TForm As {Form, New})that fixes the _form variable and Form property to type Form1.VB.NET Code:
Dim f1 As New FormSingleton(Of 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: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.VB.NET Code:
FormSingleton(Of MyForm).Show()
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:Now your code to show the form becomes:VB.NET Code:
Public Class MdiFormSingleton(Of TForm As {Form, New}) Inherits FormSingleton(Of TForm) Public Shared Sub ShowChild(ByVal mdiParent As Form) With Form .MdiParent = mdiParent .Show() .Activate() End With End Sub End ClassVB.NET Code:
MdiFormSingleton(Of MyForm).ShowChild(Me)




Reply With Quote