Saturday, December 12, 2020

[ADVENT 2020] F# Advent 2020: Revisiting Windows Forms and WPF in .NET 5.0 and hello F# 5.0

 Hi my blog readers!

This year, we have lots of exciting news on .NET Core land: the release of .NET 5.0 and also the release of new language version of F# and C#!

Last year, I discuss about how to write F# code with project support for Windows Forms/WPF in .NET Core 3.1. Also I'll showcase simple sample of latest new F# 5.0 features. What about .NET 5.0?

PS: .NET 5.0 is not .NET Framework. It is actually .NET Core version 5.0, and Microsoft describe as no "Core" branding from .NET 5.0 going forward. See also https://docs.microsoft.com/en-us/dotnet/core/dotnet-five#net-50-doesnt-replace-net-framework

In .NET 5.0, the TFM can be explicitly stated to support the underlying OS. Current .NET Core 3.1 has no TFM with OS directly (so does previous version before 3.1.

This means that in .NET 5.0 and later we should not use .NET Core Windows desktop SDK support like we have in .NET Core 3.1 and 3.0. 

As always, since .NET Core 3.0 and until 5.0, there's no default project template support to create Windows Forms/WPF project using F#. However, we can still code Windows Forms/WPF using the same way we use in my previous F# Advent 2019 blog. Again, with a twist of .NET 5.0 feature 😊

Now let's look at how the current .NET 5.0 create WinForms/WPF project from dotnet CLI.

To create a new winforms app project in .NET 5.0, we can use the same template in 3.1 like this example:

dotnet new winforms -n CSNet50Winforms

Let's look at the generated C# project: 

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net5.0-windows</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>

</Project>

We can see we have two noticeable features:

  1. We can just use default "Microsoft.NET.Sdk" SDK
  2. TFM is set to .NET 5.0 with Windows

Now we apply this to F# project, with the same model of SDK and the TFM as above. The fact is that this SDK project model alongside with TFM is actually not enforcing programming language support, because although Winforms and WPF provides C# and VB support, we can also use the same SDK for F# as well.

Let's start create new console project using F#, and name it FSWindowsDesktop using dotnet CLI:

dotnet new console -n FSWindowsDesktop -lang F#

We'll have this fsproj generated:


Change TFM from net5.0 to net5.0-windows, and also change OutputType to WinExe.

The output type change is important, because we have to explicitly tell the project that we have to mark the resulting Exe as Windows executable to run the app for Windows. See also the technical reason about this change since .NET 5.0: https://docs.microsoft.com/en-us/dotnet/core/compatibility/windows-forms/5.0/automatically-infer-winexe-output-type

Open the Program.fs, then copy the content of Program.fs from my previous .NET Core 3.1, then build it using dotnet build: (I name the project to same FSWindowsDesktop)

dotnet build FSWindowsDesktop\FSWindowsDesktop.fsproj

Then run it! Or, you can also compile and run the project using "dotnet run".

Now we're going to update the code to use one of the cool F# 5.0 features, the string interpolation!

Update the program.fs to be like this:


Note line 21, we use string interpolation to represent the name of the field/variable. It is useful, because now we could avoid compile error especially when the field/variable name changed!

I added the size of the mainForm, because we need to see the title of the form changed to include the string interpolation, combined with other new feature of "nameof". Run the code and we will see this WinForms window:


There you have Windows Forms project in F#! 
This time, with demo of string interpolation, and with also a sample of new "nameof" feature to include the name of the variable/module/symbol as string expression.

As always, the full code is available on my GitHub repo: https://github.com/eriawan/netcore-fsharp-sample

Enjoy and celebrate F# Advent 2020 and happy holiday and Merry Christmas, everyone! 





No comments:

Post a Comment