C# Winforms .Net 5: Load() of base UC is called before Ctor of derived UC is finished
See original GitHub issue.NET 5.0.13 VS 2019: v.16.11.9 both x86 and x64
Have you experienced this same bug with .NET Framework?: NO
I first seeked for advice on my problem on stackoverflow (https://stackoverflow.com/questions/70882286/, contains some kind of history and other details), but I think it also belongs here, because this is where the relevant developers are active.
We have migrated our projects from .Net Framework 4.8 to .Net 5. Now we see a very strange issue: If the display language of our application is set to something different than English, we get an Exception during the application start. The exception is raised in a UserControl with 3 levels of inheritance:
- base, lets call it UCImageObject
- first derived UCImageObjectStandard : UCImageObject
- second derived UCImgObjStd_Circle : UCImageObjectStandard
UCImageObjectStandard contains another UC (“UCTolerance”) with AutoScaleMode=DPI
and some Labels with AutoSize=true
.
If the language remains English, the label’s text is not changed, because the english-coded texts on the labels are identical with the english texts from our language database. Therefore, the label’s size also stays the same. And then there is no need to scale them:
(I stepped through the .Net 5.0.13 source code to find out)
System.Windows.Forms.Control.ScaleControl(SizeF includedFactor, SizeF excludedFactor, Control requestingControl)
line 10131: if (includedSpecified != BoundsSpecified.None)
is false, if the label’s text and size are not changed.
IF the language is set to anything but english, the label’s text and size are changed, and the ScaleControl()
(line 10133) is executed. The problem is, that finally a handle of UCImageObject
is created and its Load
event is raised (see stack frame 82 in the following stacktrace), although the constructors of UCImageObjectStandard
has not been finished (stack frame 41).
The Load()
event method of UCImageObject
then calls a virtual Init()
method, which is overridden in UCImageObjectStandard
. The UCImageObjectStandard.Init()
is then executed before the UCImageObjectStandard..ctor
has finished, which of course is wrong, and in our case this causes the exception.
The strange thing is, that this has worked well for years in .Net Framework 4.8. But it seems that changes have been made in .Net Core or .Net 5. I think I have recently read a probably related issue about the early creation (or late? or in wrong order?) of a Winforms UC handle, but I cannot find it anymore.
Can anybody tell me what has changed? It’s wrong to call an overridden method in the ctor of classes that use inheritance. But should we also avoid calling an overridden method in the Load event?
Stacktrace (frame numbers added by me): 82 at SMCore.UIWF.UCImageObject.UCImageObject_Load(Object i_sender, EventArgs i_eventArgs) 81 at System.Windows.Forms.UserControl.OnLoad(EventArgs e) 80 at System.Windows.Forms.UserControl.OnCreateControl() 79 at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible) 78 at System.Windows.Forms.Control.CreateControl() 77 at System.Windows.Forms.Control.WmShowWindow(Message& m) 76 at System.Windows.Forms.Control.WndProc(Message& m) 75 at System.Windows.Forms.ScrollableControl.WndProc(Message& m) 74 at System.Windows.Forms.ContainerControl.WndProc(Message& m) 73 at System.Windows.Forms.UserControl.WndProc(Message& m) 72 at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 71 at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 70 at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, WM msg, IntPtr wparam, IntPtr lparam) 69 at Interop.User32.CreateWindowExW(WS_EX dwExStyle, Char* lpClassName, String lpWindowName, WS dwStyle, Int32 X, Int32 Y, Int32 nWidth, Int32 nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInst, Object lpParam) 68 at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp) 67 at System.Windows.Forms.Control.CreateHandle() 66 at System.Windows.Forms.Control.get_Handle() 65 at System.Windows.Forms.Control.get_ShowKeyboardCues() 64 at System.Windows.Forms.ControlPaint.CreateTextFormatFlags(Control control, ContentAlignment textAlign, Boolean showEllipsis, Boolean useMnemonic) 63 at System.Windows.Forms.Label.CreateTextFormatFlags(Size constrainingSize) 62 at System.Windows.Forms.Label.GetPreferredSizeCore(Size proposedConstraints) 61 at System.Windows.Forms.Control.GetPreferredSize(Size proposedSize) 60 at System.Windows.Forms.Label.GetPreferredSize(Size proposedSize) 59 at System.Windows.Forms.Control.get_PreferredSize() 58 at System.Windows.Forms.Label.SetBoundsCore(Int32 x, Int32 y, Int32 width, Int32 height, BoundsSpecified specified) 57 at System.Windows.Forms.Control.ScaleControl(SizeF factor, BoundsSpecified specified) 56 at System.Windows.Forms.Control.ScaleControl(SizeF includedFactor, SizeF excludedFactor, Control requestingControl) 55 at System.Windows.Forms.Control.Scale(SizeF includedFactor, SizeF excludedFactor, Control requestingControl) 54 at System.Windows.Forms.Control.ScaleChildControls(SizeF includedFactor, SizeF excludedFactor, Control requestingControl, Boolean updateWindowFontIfNeeded) 53 at System.Windows.Forms.ContainerControl.Scale(SizeF includedFactor, SizeF excludedFactor, Control requestingControl) 52 at System.Windows.Forms.Control.ScaleChildControls(SizeF includedFactor, SizeF excludedFactor, Control requestingControl, Boolean updateWindowFontIfNeeded) 51 at System.Windows.Forms.Control.Scale(SizeF includedFactor, SizeF excludedFactor, Control requestingControl) 50 at System.Windows.Forms.Control.ScaleChildControls(SizeF includedFactor, SizeF excludedFactor, Control requestingControl, Boolean updateWindowFontIfNeeded) 49 at System.Windows.Forms.Control.Scale(SizeF includedFactor, SizeF excludedFactor, Control requestingControl) 48 at System.Windows.Forms.Control.ScaleChildControls(SizeF includedFactor, SizeF excludedFactor, Control requestingControl, Boolean updateWindowFontIfNeeded) 47 at System.Windows.Forms.ContainerControl.Scale(SizeF includedFactor, SizeF excludedFactor, Control requestingControl) 46 at System.Windows.Forms.ContainerControl.PerformAutoScale(Boolean includedBounds, Boolean excludedBounds) 45 at System.Windows.Forms.ContainerControl.PerformNeededAutoScaleOnLayout() 44 at System.Windows.Forms.ContainerControl.OnLayoutResuming(Boolean performLayout) 43 at System.Windows.Forms.Control.ResumeLayout(Boolean performLayout) 42 at SMCore.UIWF.UCImageObjectStandard.InitializeComponent() 41 at SMCore.UIWF.UCImageObjectStandard…ctor() 40 at SMCore.UIWF.UCImgObjStd_Circle…ctor() 29 at SMCore.UIWF.UCImageObject.Create(EnumType i_type, UCImageObject& io_ucImageObject) 28 at SMCore.UIWF.UCImageObject.ShowData(UCImageObject& io_ucImageObject, CImageObject i_imageObject) 27 at DI.UIWF.UCJobCreatorSettings.ucImageObjectList_SelectionChanged(Object i_oSender, EventArgs i_oEventArgs) 26 at SMCore.UIWF.UCImageObjectList.OnSelectionChanged(Int32 i_imageObjectID) 25 at SMCore.UIWF.UCImageObjectList.dgvImageObjects_SelectionChanged(Object i_sender, EventArgs i_eventArgs) 24 at SMCore.UIWF.UCImageObjectList.ShowData(CImageObjectList i_imageObjectList) 23 at DI.UIWF.UCJobCreatorSettings.Init(CImageObjectList i_oImageObjectList, IList`1 i_listoImageAcquisitionDeviceInfo) 22 at DI_JobEditor.UIWF.frmMain.Init_UI_Settings() 21 at DI_JobEditor.UIWF.frmMain.frmMain_Load(Object i_oSender, EventArgs i_oEventArgs) 20 at System.Windows.Forms.Form.OnLoad(EventArgs e) 19 at System.Windows.Forms.Form.OnCreateControl() 18 at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible) 17 at System.Windows.Forms.Control.CreateControl() 16 at System.Windows.Forms.Control.WmShowWindow(Message& m) 15 at System.Windows.Forms.Control.WndProc(Message& m) 14 at System.Windows.Forms.ScrollableControl.WndProc(Message& m) 13 at System.Windows.Forms.ContainerControl.WndProc(Message& m) 12 at System.Windows.Forms.Form.WmShowWindow(Message& m) 11 at System.Windows.Forms.Form.WndProc(Message& m) 10 at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 09 at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 08 at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, WM msg, IntPtr wparam, IntPtr lparam) 07 at Interop.User32.ShowWindow(IntPtr hWnd, SW nCmdShow) 06 at System.Windows.Forms.Control.SetVisibleCore(Boolean value) 05 at System.Windows.Forms.Form.SetVisibleCore(Boolean value) 04 at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(msoloop reason, ApplicationContext context) 03 at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(msoloop reason, ApplicationContext context) 02 at System.Windows.Forms.Application.Run(Form mainForm) 01 at DI_JobEditor.UIWF.Program.Main(String[] args)
Minimal repro: not ready yet.
Issue Analytics
- State:
- Created 2 years ago
- Comments:11 (5 by maintainers)
Top GitHub Comments
@Philip-Wang01 okay, I understand. Thank you all for your support. Unfortunately, .NET 6 requires updating VS from 2019 to 2022, which we need to buy. Using .NET 6 is on our plan, but not short-term. Our workaround is setting
AutoScaleMode=None
because we don’t use it anyway. We will use .NET 6 in the future for different reasons, and the bugfix for this issue is one of it, to avoid that this problems will arise again.@dreddy-work We verified this issue in .NET 5.0, 6.0 and 7.0, this issue only repro on 5.0, not repro on 6.0 and 7.0, please see following video:
.NET 5.0:
.NET7.0: