Code Focused

Magic Forms Access in Visual Basic and C#

Look behind the curtain on this one, and you'll see that code is quite magical in and of itself.

Accessing a specific form within a Visual Basic Windows Forms application is magical. Simply naming the form in any part of your source code causes that form to--presto--magically pop into existence:

Form2.ShowDialog()
' ----- And there it is!

Behind the scenes, Visual Basic is treating the form mention as a shortcut to the My.Forms pseudo-collection:

My.Forms.Form2.ShowDialog()

This is a little more informative, but you still can't tell what's really going on, because it's magic. If you could peer inside the My.Forms feature, you might find Visual Basic adding parallel form access points for every Form-derived class you include in your application, as shown in Listing 1.

Listing 1: My.Forms Module 
Partial Friend Module My.Forms
  ' ----- Internal, hidden storage for the magic form.
  Private InternalForm2 As WindowsApplication1.Form2 = Nothing

  ' ----- The public face of the magic form.
  Public Property Form2 As WindowsApplication1.Form2
    Get
      ' ----- Ensure a form always appears when requested.
      If (InternalForm2 Is Nothing) Then _
        InternalForm2 = New WindowsApplication1.Form2
      Return InternalForm2
    End Get
    Set(value As WindowsApplication1.Form2)
      ' ----- Allow clearing, but not overwriting, of form.
      If (value Is Nothing) Then
        InternalForm2 = Nothing
      Else
        Throw New Exception("That's a no-no.")
      End If
    End Set
  End Property
End Module

So, it's not magic, it's just code. Which means it's just like C#, because -- and learning this is part of growing up and becoming an adult -- the C# language has no magic. It also means you can do the same kind of form-magic thing in C#, if you add similar code, as shown in Listing 2.

Listing 2: My.Forms Module a la C# 
static internal partial class MyForms
{
  // ----- Internal, hidden storage for the magic form.
  private static WindowsFormsApplication1.Form2 InternalForm2 = null;

  public static WindowsFormsApplication1.Form2 Form2
  {
    get
    {
      // ----- Ensure a form always appears when requested.
      if (InternalForm2 == null)
        InternalForm2 = new WindowsFormsApplication1.Form2();
      return InternalForm2;
    }
    set
    {
      // ----- Allow clearing, but not overwriting, of form.
      if (value == null)
        InternalForm2 = null;
      else
        throw new Exception("That's a no-no.");
    }
  }
}

Now you can do the magic in C#:

MyForms.Form2.ShowDialog();

A big downside to this code is that you must add it for every form included in your project. You could inject yourself into the Roslyn code generation process and emit the necessary partial MyForms class elements on a per-Form basis. Another option would be to use Reflection to scan through your assembly at runtime, looking for valid forms, and providing access to each one through an indexer or similar construct. But those sound like a lot of work. Don't those sound like a lot of work to you?

Of course, all of this begs the question as to whether this is the best way of invoking forms in a Windows Forms application. The traditional way of creating forms in C#, via as-needed instantiation, is probably the best way to manage form lifetimes in both C# and Visual Basic:

// ----- The best C# way...
(new WindowsFormsApplication1.Form2()).ShowDialog();

' ----- And its Visual Basic equivalent...
Call (New WindowsApplication1.Form2).ShowDialog()

But that's just code, not magic. And every program needs a little magic now and then.

About the Author

Tim Patrick has spent more than thirty years as a software architect and developer. His two most recent books on .NET development -- Start-to-Finish Visual C# 2015, and Start-to-Finish Visual Basic 2015 -- are available from http://owanipress.com. He blogs regularly at http://wellreadman.com.

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events