Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
What’s new for the WinForms Visual Basic Application Framework
1
What’s new for the WinForms Visual Basic Application Framework

Klaus Loeffelmann

Melissa Trevino

March 9th, 202334

.NET from version .NET Core 3.1 up to .NET 7 has plenty of advantages over .NET

Framework: it provides performance improvements in almost every area, and those

improvements were an ongoing effort over each .NET version. The

latest improvements in .NET

6
and

.NET

7
are

really worth checking out.

Migrating your Windows Forms (WinForms) Visual Basic Apps to .NET 6/7+ also

allows to adopt modern technologies which are not (or are no longer) supported in .NET

Framework. EFCore is one example: it is

a modern Entity Framework data access technology that enables .NET developers to

work with database backends using .NET objects. Although it is not natively

supported for VB by Microsoft, it is designed in a way that it is easy for the

community to build up on it and provide code generation support for additional

languages like Visual Basic
. In

that context there are also changes and improvements in the new WinForms

Out-of-Process Designer for .NET, especially around Object Data

Sources
.

For the WinForms .NET runtime, there are a series of improvements in different

areas which have been introduced with the latest releases of .NET:

The new Visual Basic Application Framework Experience

In contrast to the project property Application Framework Designer experience in

earlier versions of Visual Studio and for .NET Framework, you will noticed that

the project properties UI in Visual Studio has changed. It’s style is now in

parity with the project properties experience for other .NET project types: we

have invested into modernizing the experience for developers, focusing on

enhancing productivity and a modern look and feel.

We’ve added theming and search to the new experience. If this is your first time

you’re working with the new project properties experience in Visual Studio, it’s

a good idea to read up on the the introductory

blog
.

In contrast to C# projects, Visual Basic Application Framework projects use a

special file for storing the Application Framework project settings: the

Application.myapp file. We’ll talk more about the technical details of how

this file connects the project settings to the VB project specific code

generation of the
Code:
My
namespace later, but one thing to keep in mind is how the

UI translates each property’s value to this file:
  • Windows Visual Styles is to determine if the application will use the most

    current version for the Control Library comctl.dll to provide control

    rendering with modern visual styling. This setting translates to the value

    Code:
    EnableVisualStyles
    of type
    Code:
    Boolean
    inside of Application.myapp.

  • Single-instance application is to determine if the application will prevent

    users from running multiple instances of the application. This setting is

    switched off by default, which allows multiple instances of the application to

    be run concurrently. This setting translates to the value
    Code:
    SingleInstance
    of

    type
    Code:
    Boolean
    .

  • Save user settings on exit is to determine if the application settings are

    automatically saved when an app is about to shut down. The settings can be

    changed with the settings editor. In contrast to .NET Framework, a new Visual

    Basic Application Framework App doesn’t contain a settings file by default,

    but you can easily insert one over the project properties, should you need

    one, and then manage the settings

    interactively
    .

    Adding to the list of settings automatically generates respective code, which

    can be easily access over the
    Code:
    My
    object in the Visual Basic Application

    Framework at

    runtime
    .

    This settings translates to the value
    Code:
    SaveMySettingsOnExit
    of type

    Code:
    Boolean
    .

  • High DPI mode is to identify the application-wide HighDpiMode for the

    application. Note that this setting can be programmatically overridden through

    the
    Code:
    HighDpiMode

    property


    of the
    Code:
    ApplyApplicationDefaultsEventArgs
    of the
    Code:
    ApplyApplicationDefaults


    application event. Choose from the following setting:
    • DPI unaware (0): The application window does not scale for DPI changes and

      always assumes a scale factor of 100%. For higher resolutions, this will

      make text and fine drawings more blurry, but may impose the best setting for

      some apps which demand a high backwards compatibility in rendering content.

    • DPI unaware GDI scaled (4): similar to DPI unaware, but improves the

      quality of GDI/GDI+ based on content. Please note that this mode will not

      work as expected, when you have enabled double

      buffering


      for control rendering via
      Code:
      OnPaint
      and related functionality.

    • Per monitor (2): Per-Monitor DPI allows individual displays to have their

      own DPI scaling setting. WinForms doesn’t optimize for this mode, and

      Per-Monitor V2 should be used instead.

    • Per monitor V2 (3): Per-Monitor V2 offers more advanced scaling features

      such as improved support for mixed DPI environments, improved display

      enumeration, and support for dynamically scaling on-client area of windows.

      In WinForms common controls are optimized for this high dpi mode. Please

      note the events

      Form.DpiChange,

      Control.DpiChangedAfterParent

      and

      Control.DpiChangeBeforeParent,

      when your app need to scale up or down content based on a changed DPI

      environment, for example, when the user of your app has dragged a Form from

      one monitor to another monitor with a different DPI setting.

    • System aware (1): The application queries for the DPI of the primary

      monitor once and uses this for the application on all monitors. When content

      in Forms is dragged from one monitor to another with a different HighDPI

      setting, content might become blurry. SystemAware is WinForm’s most

      compatible high-dpi rendering mode for all supported controls.

  • Authentication mode is to specify the method of identifying the logged-on

    user, when needed. The setting translates to the value
    Code:
    AuthenticationMode
    as

    an enum value of type
    Code:
    Integer
    :
    • 0: The
      Code:
      WindowsFormsApplicationBase(AuthenticationMode)
      constructor does

      not automatically initialize the principal for the application’s main

      thread. It’s completely the developer’s task, to manage authentication for

      the user.

    • 1: The
      Code:
      WindowsFormsApplicationBase(AuthenticationMode)
      constructor

      initializes the principal for the application’s main thread with the current

      user’s Windows user info.

  • Shutdown mode is to to indicate which condition causes the application to

    shut down. This setting translates to the value
    Code:
    ShutdownMode
    as an enum

    value of type
    Code:
    Integer
    (Note: Please also refer to the application event

    ShutDown

    and the further remarks down below.):
    • 0: When the main form closes.

    • 1: Only after the last form closes.

  • Splash screen represents the name of the form to be used as a splash screen

    for the application. Note that the file name does not need to include the

    extension (.vb). This setting translates to the value
    Code:
    SplashScreen
    of type

    Code:
    String
    .

    Quote:Note: you will may be missing the settings for the Splash dialog up to

    Visual Studio 2022 version 17.5. For a workaround, read the comments in

    the section “A look behind the scenes”. To recap: a “Splash” dialog is

    typically displayed for a few seconds when an application is launched.

    Visual Basic has an item template which you can use to add a basic splash

    dialog to your project. It usually displays the logo or name of the

    application, along with some kind of animation or visual effects, to give

    users the impression that the application is loading or initializing. The

    term “splash” in this context is used because the dialog is designed to

    create a splash or impact on the user, drawing their attention to the

    application while it loads.

  • Application Framework is saved both in the Application.myapp file and the

    .vbproj file:
    • Application.myapp saves the setting
      Code:
      MySubMain
      of type
      Code:
      Boolean
      to

      identify if the Application Framework is enabled.

    • .vbproj uses the setting
      Code:
      MyType
      for identifying the usage of the

      Application Framework for a VB project. If the Application Framework is

      enabled, the value is WindowsForms; if the Application Framework is

      disabled, the value is WindowsFormsWithCustomSubMain.

  • Startup object is the name of the form that will be used as the entry

    point, without its filename extension. Note: this property is found in the

    project property Settings under the General section, and not in the

    Application Framework section. This setting translates to the value
    Code:
    MainForm
    of type

    Code:
    String
    , when the Application Framework is activated. The start object setting in

    the .vbproj file is ignored in that case – see also the comments below on this

    topic.

Custom constants new look

We are introducing a new custom constants-control in the modernized Project

Property Pages for VB Projects, that allows to encode the input to the format

key=”value”. Our goal is that users will be able to input their custom constants

in a more streamlined key-value pair format, thus enhancing their productivity.

Feedback is welcomed – if you have any comments or suggestions, feel free to

reach out to the project system

team
by filing a new issue or

comment on existing ones.

A look behind the scenes of the WinForms VB Application Framework

The way basic properties and behaviors of a WinForms app are controlled and configured is fundamentally different between C# and Visual Basic. In C#, every app

starts with a static method called
Code:
main
which can usually be found in a file

called Program.cs, and in that
Code:
main
method all the setting get applied.

That is different in Visual Basic. Since VB Apps in WinForms are based on the

Application Framework runtime, there are a few features, which aren’t

intrinsically available to C# WinForms apps to begin with, like configuring to

automatically show Splash dialogs (see below) or ensure a single instance

application start. Since you configure most of the parts of your app

interactively in VB with the settings described above at design time, the actual

code which honors or ensures those settings later at runtime is mostly

code-generated and somewhat hidden behind the scenes. The starting point of a VB

app is therefore not so obvious. There are also a series of differences in .NET

Visual Basic apps when it comes to hooking up event code which is supposed to

run, for example when a VB WinForms app starts, ends, or runs into an unhandled

exception – just to name a few examples.

That all said, technically Visual Basic doesn’t break any fundamental rules.

Under the hood, there is of course a
Code:
Shared Sub Main
when you activate the

Application Framework. You just do not write it yourself, and you don’t see it,

because it is generated by the VB compiler and then automatically added to your

Start Form. This is done by activating the VB compiler switch

Code:
/main
.

At the same time, when you are activating the Application Framework, a series of

conditional compiler constants are defined. One of the constants is called

Code:
_mytype
. If that constant is defined as
Code:
Windows
then the VB compiler

generates all the necessary infrastructure code to support the Application

Framework. If that constant is defined as
Code:
WindowsFormsWithCustomSubMain

however, the VB compiler just generates the bare minimum infrastructure code and

doesn’t apply any settings to the WinForms app on startup. The latter happens,

when you deactivate the Application Framework. This setting is stored in the

vbproj project file, along with the Start Form. What’s important to know

though in this context: only in the case of
Code:
WindowsFormsWithCustomSubMain
, so

with the Application Framework deactivated, is the Start Form definition

actually taken from the vbproj file. When the Application Framework is

activated however then that is the case when the aforementioned

Application.myapp file is used as the settings container. Note, that by

default you cannot find that file in the solution explorer.

You need to make sure first to show all files for that project (see screenshot

above). Then you can open the My Project-folder and show that setting file in

the editor by double-clicking it in the solution explorer. The content of that

file looks something like this:

Code:
<?xml version="1.0" encoding="utf-16"?> <MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <MySubMain>true</MySubMain> <MainForm>Form1</MainForm> <SingleInstance>false</SingleInstance> <ShutdownMode>0</ShutdownMode> <EnableVisualStyles>true</EnableVisualStyles> <AuthenticationMode>0</AuthenticationMode> <SaveMySettingsOnExit>true</SaveMySettingsOnExit> <HighDpiMode>3</HighDpiMode> </MyApplicationData>

Note: Visual Studio 2022 before version 17.6 (Preview 3) won’t have the

option to pick a Splash Dialog interactively, as mentioned above. We will have

an interactive designer for setting the splash form only from that version on

on. Up to then, you can manually patch the Application.myapp file to trigger

the code generation for the Splash dialog. Insert the following line of code in

that file and save the changes.

Code:
<SplashScreen>SplashDialog</SplashScreen>

When you do this, make sure not to include the filename extension (.vb) in

that definition, because otherwise the required code does not get generated.

Application.myapp as the source for code generation

Now, if you take a closer look at that file’s properties in the property

browser, you’ll see that it is triggering a custom tool which is invoked

whenever that file is saved.

And that custom tool generates VB code which you

can find under the Application.myapp node in the Solution Explorer in

Application.Designer.vb. It does the following:
  • It defines a
    Code:
    Friend Partial Class MyApplication
    . With the Application

    Framework enabled, that class is inherited from

    Code:
    WindowsFormsApplicationBase
    .

    You don’t see that
    Code:
    Inherits
    statement here and the reason is that the major

    part of that Class’

    definition


    is injected by the Visual Basic compiler based on the earlier defined

    conditional constant
    Code:
    _myapp
    .

  • It generates the code to apply all the settings which were saved in

    Application.myapp file.

  • It creates code for a method which overrides

    Code:
    OnCreateMainForm
    .

    In that method, it assigns the Form, which is defined as the start form in the

    Application.myapp file.

Quote:Warning: The Application.Designer.vb is not supposed to be edited, as it’s

auto-generated. Any changes will be lost as soon as you make changes to Application.myapp. Instead, use the project properties UI.

Now, the class which is injected by the compiler is also responsible for

generating everything which the Visual Basic Application Framework provides you

via the
Code:
My
namespace. The
Code:
My
namespace simplifies access to frequently used

information about your WinForms app, your system, or simplifies access to

frequently used APIs. Part of the
Code:
My
namespace for an activated Application

Framework is the
Code:
Application
property, and its return type is of exactly that

type which is defined by the class generated based on your Application Settings

and then merged with the injected Visual Basic compiler file mentioned earlier.

So, if you access
Code:
My.Application
you are basically accessing a single instance

of the
Code:
My.MyApplication
type which the generated code defines.

With this context understood, we can move on to how two additional features of

the Application Framework work and can be approached. The first one is extending

the
Code:
My
namespace with additional function areas. We won’t go too much into

them, because there are detailed docs about the
Code:
My
namespace and how to

extend

it
.

An even more important concept to understand are the Application Events which are

provided by the Application Framework. Since there isn’t a good way to intercept

the startup or shut down of an app (since that code gets generated

and sort of hidden inside the main Form) Application Events are the way to be

notified of certain application-global occurrences.

Note in this context, that there is a small breaking change in the UI: while in

.NET Framework, you had to insert a code file named ApplicationEvents.vb via

the Property Settings of the VB project, in a .NET Core App this file will be

there from the start when you’ve created a new Application Framework project.

To wire up the available Application events, you open that ApplicationEvent.vb

code file, and then you select ApplicationEvents from the Object drop-down list,

and the application event you want to write up from the events list:

As you can see, the ApplicationEvent.vb code file again extends the
Code:
MyApplication
class – this time by the events handler you place there on demand. The options you have here are:

Note: More general information about the Visual Basic Application Model is provided through the Microsoft Learn Docs about this topic. Also note, that, on top of the extensibility of the
Code:
My
namespace, this Application Model also has extensibility points which are also described in great detail by the respective docs.

Summary

With the new and modernized project properties pages, WinForm’s Application

Framework is ready for new, .NET 6,7,8+ based Visual Basic Apps to develop. It’s

also the right time to think about modernizing your older .NET Framework based

VB Apps and bring them over to .NET 6,7,8+. WinForms and the .NET runtime

deliver countless new features and provide considerable performance improvements

for your apps in almost every area. Visual Basic and the Visual Basic

Application Framework are and continue to be first class citizens and are fully

supported in WinForms. Our plans are to continue modernizing around the VB App

Framework in the future without breaking code for existing projects.

And, as always: Feedback about the subject matter is really important to us, so

please let us know your thoughts and additional ideas! Please also note that the

WinForms .NET and the Visual Basic Application Framework runtime is open source,

and you can contribute! If you have general feature ideas, encountered bugs, or

even want to take on existing issues around the WinForms runtime and submit PRs,

have a look at the WinForms Github repo.

If you have suggestions around the WinForms Designer feel free to file new

issues there as well.

Happy coding!
Reply

Users browsing this thread:
1 Guest(s)


Forum Jump: