WI01041726 - Legacy Control Migration: Menu Stack#8
Open
WI01041726 - Legacy Control Migration: Menu Stack#8
Conversation
Port real implementations for Menu, MenuItem, ContextMenu, and MainMenu, replacing compatibility shims. Rewire host integration in Control and Form, including event/message handling and menu merging. Remove obsolete/hide attributes and throw-only stubs. Add Win32 interop for menu handling via LegacyMenuInteropCompat.cs. Restore menu item collections, owner-draw, MDI window list, and shortcut support. Add focused test project and demo for menu stack validation. Update solution, CI workflows, documentation, and versioning to reflect new implementation phase.
Replaces and expands legacy tests for MainMenu, ContextMenu, Menu, MenuItem, and MenuItemCollection with comprehensive, modern xUnit tests. Introduces CommonTestHelper for reusable theory data and a local CommonMemberDataAttribute. Updates .csproj for analyzer suppressions and test SDK. Ensures improved coverage of constructors, properties, events, merging, shortcuts, and sizing logic, with robust edge case and error handling validation.
Add proper WM_DRAWITEM and WM_MEASUREITEM handling for owner-drawn menu items in Control. Refactor submenu creation for clarity. Add tests to verify DrawItem and MeasureItem events are raised when receiving the corresponding messages. Includes reflection helpers and test infrastructure improvements.
Refactored MenuItem MDI popup tests by introducing an enum for test scenarios and using TheoryData for test cases. Added helper methods to create MDI parent forms, replacing inline setup. Improved readability and maintainability without changing test logic.
Added support for running the release workflow on pull requests to main. PR builds now use an auto-generated version ("0.0.0-pr.[PR number].[run number]") and skip release/nuget publishing steps. Version validation and assignment logic updated; build step uses computed version. Fixed minor comment typos.
…eTrimAnalyzer condition syntax
…s, and test result uploads
…nd PrivateAssets attributes for improved packaging
…tions from `src/System.Windows.Forms/src/Resources`
…d streamline package creation
…in System.Windows.Forms.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Legacy Control Migration: Menu Stack
Scope
This document describes the current Menu Stack migration work for the legacy WinForms menu surface:
MenuMenuItemContextMenuMainMenuControl.ContextMenuForm.MenuForm.MergedMenuIt is based on the actual changes currently on this branch, not just on the original migration checklist.
Current Status
The Menu Stack is the active migration area.
The branch has already restored the core runtime surface and the main host integration points. What remains is focused validation, plus product cleanup around obsolete warnings, IntelliSense visibility, and package messaging.
What Changed On This Branch
1. The hollow menu shims were replaced with runtime implementations
The following legacy menu types are no longer just binary-compatibility shells:
MenuMenuItemContextMenuMainMenuThe restored code now brings back behavior such as:
This is the important architectural shift: the branch is no longer trying to simulate support with metadata-only stubs. It is restoring the runtime model.
2.
Menu.csnow carries the real menu tree infrastructureThe restored
Menuimplementation now provides the shared runtime base for the whole stack.Key behavior brought back includes:
WM_MENUCHARhandling for owner-draw menusMenuItemCollectionimplementationOne practical cleanup tied to this change is that the old split shim file
Menu.MenuItemCollection.cswas removed because the real collection implementation now lives insideMenu.cs.3.
MenuItem.csnow restores the bulk of menu-item behaviorMenuItemis where most of the menu-state and menu-event machinery lives, and the current branch restores that implementation rather than preserving the old throw-only shell.The restored work includes:
MenuItemDataThis is one of the clearest signals that the migration is runtime-first now: the branch restored the actual stateful implementation model instead of keeping a reflection-only public shape.
4.
ContextMenu.csnow behaves like a working context menu againContextMenuwas previously a hollow shell. On this branch it now supports:PopupandCollapseeventsSourceControlRightToLeftShow(Control, Point)Show(Control, Point, LeftRightAlignment)ProcessCmdKeyThat means a control-associated legacy context menu can now participate in real interaction again instead of existing only for binary compatibility.
5.
MainMenu.csnow restores top-level form menu behaviorMainMenuhas also been turned back into a runtime type.The restored work includes:
RightToLeftThis is important because legacy menu support depends on the form being able to own and refresh a real native main menu.
6.
MenuMerge.cswas reopened as real public surfaceMenuMergeno longer carries the old obsolete-and-hidden compatibility-only presentation.That is consistent with the branch direction: once the runtime implementation is being restored, the public surface can no longer be treated purely as a dead compatibility shape.
Host Integration Restored In Core Framework Types
1.
Controlnow supports real legacyContextMenubehavior againThe branch rewired
Controlso legacy context menus participate in runtime behavior rather than acting as inert compatibility properties.The restored behavior includes:
ContextMenuproperty backed by the control property storeContextMenuChangedeventOnContextMenuChangedWmContextMenudispatch that shows the legacy menu at the expected pointHasMenuintegration so menu-aware size calculations use the correct native window metricsThat last point matters because once a form or control really has a menu again, the non-client sizing code needs to account for it.
2.
Formnow owns, merges, and refreshes legacy menus againThe
Formchanges are the other major integration point.The current branch restores:
Menuproperty backed by the property storeMergedMenupath for MDI scenariosHasMenuparticipation in size calculationUpdateMenuHandlesWM_INITMENUPOPUPWM_MENUCHARWM_UNINITMENUPOPUPThis is the host-level plumbing that makes the restored menu types usable in a real form lifecycle rather than only constructible.
3.
TreeNode.ContextMenusupport was added backThe branch also restores legacy
ContextMenusupport onTreeNode.That includes:
TreeNode.ContextMenupropertyThis is a smaller change than the
ControlandFormintegration work, but it is still important because it proves the migration is covering old usage patterns beyond top-level forms.Compatibility Interop Added For The Restored Menu Stack
The branch adds
LegacyMenuInteropCompat.csto carry Win32 compatibility wrappers and menu-related structures needed by the restored implementation.That file provides the interop support used by the menu runtime for:
This is effectively the compatibility bridge that lets the restored legacy menu code participate in the current codebase's interop layer without requiring a full historical file-for-file import.
Validation Assets Added On This Branch
1. Focused legacy test project
The branch adds
System.Windows.Forms.Legacy.Testsand wires it intoWinformsLegacy.sln.The current test coverage includes:
MainMenuTestsMenuItemTestsMenuSizeCalculationTestsThose tests specifically exercise areas that match the restored host integration:
This is the first focused verification layer for the restored stack.
2. Demo project for manual verification
The branch also adds
System.Windows.Forms.Legacy.Demoand a launcher form dedicated to legacy-control exploration.The Menu Stack demo exercises:
MainMenuMenuItemContextMenuTreeNode.ContextMenuThis is useful because a lot of menu behavior is still easiest to validate interactively before the automation coverage is complete.
Net Effect Of The Current Menu Stack Migration
The current branch has already accomplished the hard part of Phase 1:
ControlandFormintegration pointsIn other words, the Menu Stack is no longer just a design proposal on this branch. It is an implemented runtime migration that still needs validation and product cleanup.
Remaining Work
The main remaining tasks are:
EditorBrowsablebehavior now that the types are no longer hollow shims.Practical Summary
If someone asks what the current legacy-control migration is doing, the clearest answer is:
The branch is actively restoring the classic WinForms Menu Stack as working runtime behavior. It ports back the real
Menu/MenuItem/ContextMenu/MainMenuimplementation model, reconnects that model toControlandForm, and adds both automated tests and a manual demo to verify the recovered behavior.