Skip to content

Commit

Permalink
Resume invocation of OnParentHandleRecreated for child control when f…
Browse files Browse the repository at this point in the history
…orm recreates handle

Fixes #6093

Fix the regression introduced in #2262.
  • Loading branch information
RussKie committed Nov 3, 2021
1 parent a672369 commit ec704db
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -9658,7 +9658,7 @@ internal virtual void RecreateHandleCore()
// - or -
// CreateHandle is successful.
// We will move the child controls to the new parent.
if (controlSnapshot != null && GetState(States.Created))
if (controlSnapshot != null)
{
for (int i = 0; i < controlSnapshot.Length; i++)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,62 @@ public void Control_CreateParams_GetVisible_ReturnsExpected(bool visible, int ex
Assert.False(control.IsHandleCreated);
}

[WinFormsFact]
public void Control_RecreateHandleCore_invokes_OnParentHandleRecreated_for_children()
{
using Form form = new();
SubCheckedListBox checkedListBox1 = new();
SubButton button1 = new();
SubListBox listBox1 = new();
SubListView listView1 = new();

checkedListBox1.Items.AddRange(new object[] { "Foo", "Foo", "Foo" });
checkedListBox1.Location = new Point(10, 10);
checkedListBox1.Size = new Size(103, 64);

button1.Location = new Point(12, 166);
button1.Size = new Size(213, 20);

listBox1.Items.AddRange(new object[] { "Foo", "Foo", "Foo" });
listBox1.Location = new Point(12, 80);
listBox1.Size = new Size(101, 69);

listView1.Items.AddRange(new ListViewItem[] { new("Foo"), new("Foo"), new("Foo") });
listView1.Location = new Point(130, 10);
listView1.Size = new Size(121, 64);
listView1.View = View.List;

form.Controls.Add(checkedListBox1);
form.Controls.Add(button1);
form.Controls.Add(listBox1);
form.Controls.Add(listView1);

form.Show();

// This will recreate the handle.
form.ShowInTaskbar = false;

try
{
AssertHandler(button1);
AssertHandler(listView1);
AssertHandler(checkedListBox1);
AssertHandler(listBox1);
}
finally
{
form.Close();
}

return;

static void AssertHandler(IParentHandleRecreationHandler handler)
{
Assert.Equal(1, handler.OnParentHandleRecreatedCalled);
Assert.Equal(1, handler.OnParentHandleRecreatingCalled);
}
}

private class SubControl : Control
{
public SubControl() : base()
Expand Down Expand Up @@ -1046,5 +1102,83 @@ public SubControl(Control parent, string text, int left, int top, int width, int

public new void WndProc(ref Message m) => base.WndProc(ref m);
}

private class SubCheckedListBox : CheckedListBox, IParentHandleRecreationHandler
{
public int OnParentHandleRecreatedCalled { get; private set; }
public int OnParentHandleRecreatingCalled { get; private set; }

internal override void OnParentHandleRecreated()
{
OnParentHandleRecreatedCalled++;
base.OnParentHandleRecreated();
}

internal override void OnParentHandleRecreating()
{
OnParentHandleRecreatingCalled++;
base.OnParentHandleRecreating();
}
}

private class SubListBox : ListBox, IParentHandleRecreationHandler
{
public int OnParentHandleRecreatedCalled { get; private set; }
public int OnParentHandleRecreatingCalled { get; private set; }

internal override void OnParentHandleRecreated()
{
OnParentHandleRecreatedCalled++;
base.OnParentHandleRecreated();
}

internal override void OnParentHandleRecreating()
{
OnParentHandleRecreatingCalled++;
base.OnParentHandleRecreating();
}
}

private class SubButton : Button, IParentHandleRecreationHandler
{
public int OnParentHandleRecreatedCalled { get; private set; }
public int OnParentHandleRecreatingCalled { get; private set; }

internal override void OnParentHandleRecreated()
{
OnParentHandleRecreatedCalled++;
base.OnParentHandleRecreated();
}

internal override void OnParentHandleRecreating()
{
OnParentHandleRecreatingCalled++;
base.OnParentHandleRecreating();
}
}

private class SubListView : ListView, IParentHandleRecreationHandler
{
public int OnParentHandleRecreatedCalled { get; private set; }
public int OnParentHandleRecreatingCalled { get; private set; }

internal override void OnParentHandleRecreated()
{
OnParentHandleRecreatedCalled++;
base.OnParentHandleRecreated();
}

internal override void OnParentHandleRecreating()
{
OnParentHandleRecreatingCalled++;
base.OnParentHandleRecreating();
}
}

private interface IParentHandleRecreationHandler
{
int OnParentHandleRecreatedCalled { get; }
int OnParentHandleRecreatingCalled { get; }
}
}
}

0 comments on commit ec704db

Please sign in to comment.