I upgraded a WinForms App to .NET Core 3.1 these days. It's an open-source on-screen ruler created by Jeff Key in 2004, the original code was for .NET Framework 2.0, I've already upgraded it to .NET Core 3.0 in September this year, it was very smooth without any code change. But this time, .NET Core 3.1 does require some code changes. 

The project is on my GitHub: https://github.com/EdiWang/Ruler

According to Microsoft .NET Blog, .NET Core 3.1 for Windows Forms has some breaking changes by removing some controls.

The following Windows Forms controls have been removed from .NET Core 3.1:

  • DataGrid
  • ToolBar
  • ContextMenu
  • Menu
  • MainMenu
  • MenuItem

These controls were replaced with more powerful controls in .NET Framework 2.0, back in 2005. They have not been available by default in the Visual Studio Designer Toolbox for many years. As a result, we decided to remove these controls and focus only on the new ones.

And they have recommended replacements for these controls:

Old Control (API) Recommended Replacement Other associated APIs removed
DataGrid DataGridView DataGridCell, DataGridRow, DataGridTableCollection, DataGridColumnCollection, DataGridTableStyle, DataGridColumnStyle, DataGridLineStyle, DataGridParentRowsLabel, DataGridParentRowsLabelStyle, DataGridBoolColumn, DataGridTextBox, GridColumnStylesCollection, GridTableStylesCollection, HitTestType
ToolBar ToolStrip ToolBarAppearance
ToolBarButton ToolStripButton ToolBarButtonClickEventArgs, ToolBarButtonClickEventHandler, ToolBarButtonStyle, ToolBarTextAlign
ContextMenu ContextMenuStrip  
Menu ToolStripDropDown, ToolstripDropDownMenu MenuItemCollection
MainMenu MenuStrip  
MenuItem ToolstripMenuItem  

In the Ruler project, I need to migrate just the menu controls besides retargeting the runtime version.

<TargetFramework>netcoreapp3.1</TargetFramework>
Type Replacement

Replace ContextMenu with ContextMenuStrip, and replace MenuItem with ToolStripMenuItem

For example, the old code:

private readonly ContextMenu _menu = new ContextMenu();
private MenuItem _verticalMenuItem;
private MenuItem _toolTipMenuItem;

Is replaced with

private readonly ContextMenuStrip _menu = new ContextMenuStrip();
private ToolStripMenuItem _verticalMenuItem;
private ToolStripMenuItem _toolTipMenuItem;
API Differences

Shortcut Enum that used by MenuItem isn't there anymore. Replace old code:

private MenuItem AddMenuItem(string text, Shortcut shortcut = Shortcut.None)
{
    MenuItem mi = new MenuItem(text);
    mi.Click += MenuHandler;
    mi.Shortcut = shortcut;
    _menu.MenuItems.Add(mi);

    return mi;
}

with new code

private ToolStripMenuItem AddMenuItem(string text, Keys shortcut = Keys.None)
{
    ToolStripMenuItem mi = new ToolStripMenuItem(text);
    mi.Click += MenuHandler;
    mi.ShortcutKeys = shortcut;
    _menu.Items.Add(mi);

    return mi;
}

In the old Menu control, the "-" string represented a separator, which is now replaced by ToolStripSeparator. So, old code:

AddMenuItem("-");

Is now

_menu.Items.Add(new ToolStripSeparator());

Finally, the new menu looks like this:

The project is very simple, so everything works after a few code changes in .NET Core 3.1. As you can see, to replace the old controls isn't too much difficult. Hope you can also get your old project running on the latest platform soon!