Setting ComboBox.SelectedIndex in a form's constructor disables further firing of the SelectedIndexChanged event, in .NET Core. It seems it has to do with the availability of the window and control handles. It works OK in the full framework, but it fails in .NET Core. Looks like a breaking change.
Please fill the bug template provided and supply steps to reproduce/demo app.
Thank you
(where's the bug template?)
Steps for reproduction:
About the environment: Windows 10 v1093, Visual Studio 2019 16.1.6 with previews allowed, and .NET Core Preview 6.
@Olina-Zhang can you try repro it and if it repros, can you please attach a sample repro app here? Can you also check if this is a regression from .NET framework?
WindowsFormsAppCore.zip
Repro added. The repro has two forms: you don't need the second one. It's just that I first isolated the bug using a secondary form. However, you just need a single combobox in the main form to reproduce it.
@dreddy-work we can repro this issue in Core latest build, and cannot repro in .Net 4.8 latest build. It seems a regression issue in Core. Here is the sample app with same code for .Net Core and .Net framework 4.8
.Net Core:
WindowsFormsApp9.zip
.Net framework:
WindowsFormsApp8.zip
After run them:

Are there any hints or workarounds for this? That just prevents me from going beyond preview5.
Are there any hints or workarounds for this? That just prevents me from going beyond preview5.
Move any initializations involving controls from the constructor into an overridden OnHandleCreated method.
Move any initializations involving controls from the constructor into an overridden OnHandleCreated method.
Thanks but far to much effort if you have a lot of forms.
Fortunately I already have a derived ComboBox class in place. The following code in the derived class seems to successfully workaround it, too.
``` C#
private int? deferredSelectedIndex;
public override int SelectedIndex
{
get
{
return base.SelectedIndex;
}
set
{
if (!this.IsHandleCreated)
{
this.deferredSelectedIndex = value;
}
else
{
base.SelectedIndex = value;
}
}
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (this.deferredSelectedIndex.HasValue)
{
this.SelectedIndex = this.deferredSelectedIndex.Value;
this.deferredSelectedIndex = null;
}
}
```
You're right, of course.
There seems to be a similar bug with ListView where SelectedIndexChanged doesn't fire if you add items to the ListView from the constructor (noticed while debugging the otherwise separate issue #1607)
Why is this set to the future milestone? It's a pretty big hurdle to upgrade to .NET Core 3 with this compatibility issue for people who have lots of forms.
I agree, initialization in constructors is pretty common, and its a regression from Desktop Framework. Considering that other controls appear to have similar regressions the priority of fixing this might need to be reevaluated.
I've debugged into the issue comparing .NET Fx and .NET Core.
Here's the progress so far.
.NET Fx:
// eventualy get WM_REFLECT+WM_COMMAND that gets translated to SelectIndexChanged event
//
// .........
// from that point a number of messages get sent to the combobox ^^^,
// {msg=0x133 (WM_CTLCOLOREDIT) hwnd=0x40858 wparam=0xffffffff990113a4 lparam=0xa0854 result=0x0}
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd = {System.IntPtr}, int msg = 307, System.IntPtr wparam = {System.IntPtr}, System.IntPtr lparam = {System.IntPtr}) Line 799 C#
// send a message to the combobox itself
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Line 836 C#
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.DefChildWndProc(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Line 2010 C#
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.ChildWndProc(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Line 1960 C#
// {msg=0xb1 (EM_SETSEL) hwnd=0xa0854 wparam=0x0 lparam=0x7fffffff result=0x0}
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.ComboBoxChildNativeWindow.WndProc(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Line 3902 C#
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd = {System.IntPtr}, int msg = 177, System.IntPtr wparam = {System.IntPtr}, System.IntPtr lparam = {System.IntPtr}) Line 803 C#
// send a message to the edit control within the combobox
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Line 836 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.DefWndProc(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Line 5924 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WmCommand(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Line 12841 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Line 14136 C#
// {msg=0x111 (WM_COMMAND) hwnd=0x40858 wparam=0x10003e9 lparam=0xa0854 result=0x0}
// 0x40858 <-- handle of the combobox
// 0xa0854 <-- handle of the edit control within the combobox
> System.Windows.Forms.dll!System.Windows.Forms.ComboBox.WndProc(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Line 3857 C#
.NET Core
// no message is sent to the combobox!!!
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) Line 667 C#
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.DefChildWndProc(ref System.Windows.Forms.Message m) Line 2106 C#
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.ChildWndProc(ref System.Windows.Forms.Message m) Line 2048 C#
// {msg=0xb1 (EM_SETSEL) hwnd=0x2504fc wparam=0x0 lparam=0x7fffffff result=0x1}
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.ComboBoxChildNativeWindow.WndProc(ref System.Windows.Forms.Message m) Line 4104 C#
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) Line 626 C#
// send a message to the edit control within the combobox
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) Line 667 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.DefWndProc(ref System.Windows.Forms.Message m) Line 5226 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WmCommand(ref System.Windows.Forms.Message m) Line 12000 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) Line 13379 C#
// {msg=0x111 (WM_COMMAND) hwnd=0x280572 wparam=0x10003e9 lparam=0x2504fc result=0x0}
// 0x280572 <-- handle of the combobox
// 0x2504fc <-- handle of the edit control within the combobox
> System.Windows.Forms.dll!System.Windows.Forms.ComboBox.WndProc(ref System.Windows.Forms.Message m) Line 4051 C#
The call UnsafeNativeMethods.CallWindowProc(defWindowProc, m.HWnd, m.Msg, m.WParam, m.LParam) that is supposed to send a message to the combobox returns 0x01.
https://github.com/dotnet/winforms/blob/aec17fb941d399ba3dd05c6c1a4a7dfcd9f28cad/src/System.Windows.Forms/src/System/Windows/Forms/NativeWindow.cs#L667
I need some help here, Win32 isn't something I'm particluarly good with....
@Tanya-Solyanik @JeremyKuhne @dreddy-work
Investigating
ListView (#1607) and RichTextBox (#1644) also have problems firing events in .NET Core when calling certain methods in the Form constructor. Starts looking like a general problem.
Unfortunately the best I can tell so far is that this came from #1034. 馃槶 I walked back the branches of the commit tree to this change. I'm easily confused by git, so if someone can check me that would be greatly appreciated. f38a7a167d8f83924d43f8d2d8f2b03034351eb7 repros the issue. 38a0d1b738675a8417829bad95c554fe3613e062 does not.
I'll give the change a closer look tomorrow to see if I can find the culprit.
cc: @zsd4yr
I found the issue. Ordering got flipped with switching as to is. I presume the tooling was at fault here. We should audit that part of #1034 thoroughly to make sure nothing else got reordered.
This has to be one of the longest investigations I've done for such a small fix. :) Debugging the message loops is extremely painful- I've got a number of changes for V5 that will simplify the process somewhat.
Verified with latest .NET Core 3.0 Preview 9 3.0.100.14004 build, it鈥檚 not reproduced for now.
Thank you!
Most helpful comment
I found the issue. Ordering got flipped with switching
astois. I presume the tooling was at fault here. We should audit that part of #1034 thoroughly to make sure nothing else got reordered.This has to be one of the longest investigations I've done for such a small fix. :) Debugging the message loops is extremely painful- I've got a number of changes for V5 that will simplify the process somewhat.