Click here to Skip to main content
15,879,535 members
Articles / Programming Languages / XML

Use Windows Forms Designer on .NET Core 3.0 Preview

Rate me:
Please Sign up or sign in to vote.
4.43/5 (8 votes)
10 Aug 2019CPOL4 min read 36.3K   10   21
A hack tutorial that enables the use of Windows Forms Designer for .NET Core 3.0 (preview) based Windows Forms apps

Introduction

As of time of writing, Microsoft and the community are currently testing .NET Core 3.0. If you are reading this article after .NET Core 3.0's general availability, please skip the article. Otherwise, carry on.

 

In case the video frame doesn't show, please visit this link to watch the full demonstration of this article.

 

Windows Forms has been the pinnacle of maintaining business/enterprise desktop apps. Despite its archaic mechanics to develop desktop apps, Microsoft was able to recognize the strengths of the battle tested toolkit and decided to move it to the modern .NET Core platform (previously known as .NET Framework.)

So far, they managed to pull things together pretty well with the Windows Forms transition, but are missing some key components for early adopters and one of them happens to be the Windows Forms Designer; a tool built into Microsoft Visual Studio that aims to simplify user interface development. To acknowledge the Windows Forms Designer limitation in .NET Core 3.0 preview, try opening and designing any form/user control file (typically Form1.cs from a newly created project.) Hence, the result of the article's existence. This article will walk you through on how to overcome the limitation of .NET Core 3.0 preview's Windows Forms Designer without having to wait for its general availability.

Software Requirements

In order to follow along with the article, you must have the following components installed on your system:

  1. Microsoft Visual Studio 2019 - at least version 16.2.0
  2. .NET Core 3.0 preview 7 (as of the time of writing, preview 7 will be used)

Overcome the Limitation

Demonstrating the Problem

  1. Create a new Windows Forms App (.NET Core). If you can't see the entry on the left, use the convenient "Search for templates" search box and type in "Windows Forms App (.NET Core)".

    Image 1

  2. For this project, we will be naming it DotNetCore.WinForms, but you can name it anything you like, make sure to understand the concept and you'll be good to go.
  3. Without making any change yet, try opening Form1.cs file and you should be seeing something like this. Please don't be alarmed, this is normal behavior due to the fact that we are running the preview version of .NET Core 3.0. We will be solving this later on.

    Image 2

At this point, you start to get the feeling that you can't do any sort of user interface design under .NET Core 3.0 preview.

The Solution

To get around the limitation, we can use an approach where we can indirectly tap into the design of the .NET Core project by creating an additional Windows Forms project based on the fully functional .NET Framework. Please proceed till the end.

  1. Right click on the solution name and create a new solution folder with the name _TemporaryFixup.

    Image 3

  2. Under the _TemporaryFixup solution folder, create a new Windows Forms App (.NET Framework) project. If you can't see the entry on the left, use the convenient "Search for templates" search box and type in "Windows Forms App (.NET Framework)".

    Image 4

  3. For this project, we will be naming it DotNetFramework.WinForms, but you can name it anything you like.
  4. Delete the Form1.cs file.
  5. Right click on the DotNetFramework.WinForms project and click Properties.
  6. Change the default namespace to match the same as the .NET Core project; in our case, we will set it to DotNetCore.WinForms (will be explained in a few)
  7. Create a new form and name it to anything you like.

Now, let's modify Program.cs file in the DotNetFramework.WinForms project with the following:

C#
using System;
using System.IO;
using System.Linq;

namespace DotNetFramework.WinForms
{
    static class Program
    {
        private static string SourceProjectDir = 
            @"C:\Users\ahmad\source\repos\DotNetCore.WinForms\DotNetFramework.WinForms";
        private static string TargetProjectDir = 
            @"C:\Users\ahmad\source\repos\DotNetCore.WinForms\DotNetCore.WinForms";

        [STAThread]
        static void Main()
        {
            var directory = new DirectoryInfo(SourceProjectDir);

            var srcFiles = directory.GetFiles("*.Designer.cs", SearchOption.AllDirectories);

            foreach (var srcFile in srcFiles)
            {
                // Get the relative directory
                var relativeDirectory = $"{srcFile.DirectoryName.Substring
                                (SourceProjectDir.Length, 
                                srcFile.DirectoryName.Length - SourceProjectDir.Length)}";

                // Append the determined relative directory to the corresponding designer 
                // & C# source files related to the form.
                var designerFileName = $@"{relativeDirectory}\{srcFile.Name}";
                var noDesignerFileName = 
                  $@"{relativeDirectory}\{srcFile.Name.Replace(".Designer", "")}";

                var srcDesignerFile = $"{SourceProjectDir}{designerFileName}";
                var srcNoDesignerFile = $"{SourceProjectDir}{noDesignerFileName}";

                var dstDesignerFile = $"{TargetProjectDir}{designerFileName}";
                var dstNoDesignerFile = $"{TargetProjectDir}{noDesignerFileName}";

                // Create an array based on the relative location.
                var dirs = relativeDirectory.Split('\\').ToList();

                // Keep track of where were we when we created a directory.
                var currentDir = TargetProjectDir;

                // Start creating the missing directories in our target project.
                foreach (var dir in dirs)
                {
                    currentDir = Path.Combine(currentDir, dir);
                    Directory.CreateDirectory(currentDir);
                }

                // Overwrite the file to the targeted project.
                File.Copy(srcDesignerFile, dstDesignerFile, true);

                // If our UI logic is unavailable, that means we've created 
                // a new form from the source project.
                // so we copy the form's UI logic code to the target project.
                if (!File.Exists(dstNoDesignerFile) && File.Exists(srcNoDesignerFile))
                {
                    File.Copy(srcNoDesignerFile, dstNoDesignerFile, false);
                }
            }
        }
    }
}

Since we are focusing on developing our app on the .NET Core platform, we won't be needing to show any dialog from the .NET Framework counterpart. We'd rather *reflect* only the user interface design parts of the .NET Framework project to the .NET Core project. Which pretty much explains why we changed the default namespace to the .NET Framework project earlier, remember?

Make sure to modify SourceProjectDir variable to hold your .NET Framework project directory and the TargetProjectDir variable to hold the .NET Core project directory.

Next, we want to call out the .NET Framework executable everytime we want to build and run our .NET Core project. Before we move any further, build the entire solution first. Second, right click on the .NET Framework project and click on Properties, then choose Build Events from the tab on the left. On "Pre-build event command line" field, paste the following:

C#
$(TargetPath)

Finally, you can start designing your user interface elements from the .NET Framework project and reflect your changes to the .NET Core project automagically by hitting Ctrl+Shift+B and then run!

Using the Code

The provided code above is essentially a reflector. It reflects only the form files of the .NET Framework project to the .NET Core project. You may modify the code with no limits to make it do what you intend it to do.

Points of Interest

The convenience of the Windows Forms Designer has been brought back. Whether you're planning to start fresh with Windows Forms under .NET Core or migrating your existing traditional .NET Framework based project, you can now easily proceed doing so without having to wait for .NET Core 3.0's general availability.

History

  • Version 1.0 - Initial commit
  • Version 1.0.1 - Added YouTube video link for demonstration

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Lebanon Lebanon
Proudly a Computer Scientist that happens to genuinely adore programming.

Comments and Discussions

 
QuestionNo need for workaround any more. Pin
tralfazmx2-Oct-19 2:17
tralfazmx2-Oct-19 2:17 
QuestionCan we develop winform app with .net core? Pin
Mou_kol8-Aug-19 20:45
Mou_kol8-Aug-19 20:45 
AnswerRe: Can we develop winform app with .net core? Pin
Ahmad N. Chatila15-Aug-19 22:00
professionalAhmad N. Chatila15-Aug-19 22:00 
Unfortunately, this is not possible for the time being. The article provides a workaround for designing WinForms for .NET Core 3.0 preview 7 running on Windows operating systems.
AnswerRe: Can we develop winform app with .net core? Pin
Klaus Luedenscheidt17-Aug-19 18:54
Klaus Luedenscheidt17-Aug-19 18:54 
QuestionAny reason to waste time?? Pin
Thornik7-Aug-19 0:26
Thornik7-Aug-19 0:26 
AnswerRe: Any reason to waste time?? Pin
Ahmad N. Chatila7-Aug-19 4:21
professionalAhmad N. Chatila7-Aug-19 4:21 
GeneralRe: Any reason to waste time?? Pin
Thornik7-Aug-19 4:48
Thornik7-Aug-19 4:48 
GeneralRe: Any reason to waste time?? Pin
Ahmad N. Chatila8-Aug-19 1:00
professionalAhmad N. Chatila8-Aug-19 1:00 
GeneralRe: Any reason to waste time?? Pin
BillWoodruff11-Aug-19 19:52
professionalBillWoodruff11-Aug-19 19:52 
GeneralRe: Any reason to waste time?? Pin
Ahmad N. Chatila12-Aug-19 0:00
professionalAhmad N. Chatila12-Aug-19 0:00 
GeneralRe: Any reason to waste time?? Pin
BillWoodruff12-Aug-19 1:46
professionalBillWoodruff12-Aug-19 1:46 
GeneralRe: Any reason to waste time?? Pin
Ahmad N. Chatila12-Aug-19 2:03
professionalAhmad N. Chatila12-Aug-19 2:03 
AnswerRe: Any reason to waste time?? Pin
Klaus Luedenscheidt8-Aug-19 18:02
Klaus Luedenscheidt8-Aug-19 18:02 
GeneralRe: Any reason to waste time?? Pin
Ahmad N. Chatila12-Aug-19 13:00
professionalAhmad N. Chatila12-Aug-19 13:00 
GeneralRe: Any reason to waste time?? Pin
Thornik13-Aug-19 11:49
Thornik13-Aug-19 11:49 
GeneralRe: Any reason to waste time?? Pin
Klaus Luedenscheidt17-Aug-19 18:50
Klaus Luedenscheidt17-Aug-19 18:50 
AnswerRe: Any reason to waste time?? Pin
kiquenet.com11-Aug-19 22:54
professionalkiquenet.com11-Aug-19 22:54 
GeneralRe: Any reason to waste time?? Pin
Thornik13-Aug-19 11:51
Thornik13-Aug-19 11:51 
QuestionLooks very complicated Pin
Klaus Luedenscheidt6-Aug-19 18:28
Klaus Luedenscheidt6-Aug-19 18:28 
AnswerRe: Looks very complicated Pin
Ahmad N. Chatila7-Aug-19 4:24
professionalAhmad N. Chatila7-Aug-19 4:24 
GeneralRe: Looks very complicated Pin
rhde16-Sep-19 5:17
rhde16-Sep-19 5:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.