Search code examples
winformsvisual-studio-2019.net-3.5.net-4.7.2

How to troubleshoot window painting issues after migrating WinForms app from .net 3.5 to 4.7.2


We've just migrated our VS2019 dev environments for a large (~700 kloc) legacy Windows Forms application, from .NET 3.5 to .NET 4.7.2, and tripped over a problem with one windows form only, on which two very odd issues have emerged:

  1. A ContextMenuStrip coded to appear on right-click in cells in a DataGridView, does not open its sub-menus (where present) automatically on mouse hover - a click is required. ContextMenuStrips coded ostensibly the same on other forms behave normally.
  2. Opening another form from the form in question (from said ContextMenuStrip), results in the controls on that form not being painted. If another form is activated and then the opened one reactivated, the controls appear. However, opening the same form in exactly the same way from other forms gives expected behaviour.

I realise there's not much to go on here - I'm guessing that we've tripped over some obscure change between .net 3.5 and 4.7.2, but Dr Google hasn't revealed any leads so far.

It's going to be quite hard to rip stuff out in the hope of isolating the issue - we have all kinds of inherited controls and custom grid painting, much of which is key to the functionality. I haven't tried building a test case, as since the same inherited control (with DataGridView and ContextMenuStrip) works perfectly elsewhere in the same application, it doesn't seem likely that creating a test form will do anything other than work fine.

So at this stage I'd be grateful just some idea of where to look.

Environment: Visual Studio 2019 v16.11.10, .net 4.7.2, Windows Forms app, written mostly in VB.NET with a little C# in some class libraries.

Things I've tried:

  • much Googling for breaking changes between .net 3.5 and .net 4.7.2
  • commenting out a fair bit of the custom painting in the DataGridView
  • switching between x64, x86 and AnyCpu platforms
  • compiling for .NET 4.8 rather than 4.7.2 - no difference in behaviour.

... all to no avail.

Any ideas gratefully received. I'll update the question with the results of any suggestions.


Edit:

  • corrected references to ToolStripMenu - should have been ContextMenuStrip as @dr.null commented.
  • added another test: compile and run for .NET 4.8 as @dr.null commented.

Solution

  • Well it turned out to be very obscure. We discovered that the CellPainting event was running continuously, dozens of times a second.

    It turned out that the CellPainting event was triggering the CellFormatting event, in which some of the underlying DataRow values were being changed. Apparently this re-triggers the CellPainting event, hence the loop.

    Changing the code to update the underlying row value only if different from what it was already, prevented the loop, and consequently stopped the continuous repainting.

    With this change, the ContextMenuStrip behaviour returned to normal, and the form opened got its controls painted normally as well.

    What isn't explained is why we didn't have this issue before we migrated away from .NET 3.5. I can only assume some odd difference between the frameworks, as the code in question is very old and hasn't changed for several years.