Skip to content

Commit

Permalink
Fixing switching focus between ToolStrips where TabStop=true with Shi…
Browse files Browse the repository at this point in the history
…ft-Tab (port to 7.0) (#5964)

* Revert only Control.cs from commit "Fixing switching focus between ToolStrips where TabStop=true with Shift-Tab (#5842)"

(0405ba2)

* Fixing moving focus backward with Shift-Tab at ToolStrip with TabStop=true.

If we don't found any siblings, and the control is a ToolStripItem that hosts a control itself, then we shouldn't return its parent, because it would be the same ToolStrip we're currently at. Instead, we should return the control that is previous to the current ToolStrip.

Debug.Asserts from 6.0 are replaced for Exceptions with localized strings

(cherry picked from commit 0e53ce7)
  • Loading branch information
ArtemTatarinov authored Oct 13, 2021
1 parent 04c640c commit 27b6c5e
Showing 1 changed file with 48 additions and 19 deletions.
67 changes: 48 additions & 19 deletions src/System.Windows.Forms/src/System/Windows/Forms/Control.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6034,20 +6034,7 @@ public Control GetNextControl(Control ctl, bool forward)
}
else
{
ControlCollection children = GetControlCollection(ctl);

if (children is not null && children.Count > 0 && (ctl == this || !IsFocusManagingContainerControl(ctl)))
{
Control found = ctl.GetFirstChildControlInTabOrder(forward: false);
if (found is not null)
{
return found;
}
}

// Cycle through the controls in reverse z-order looking for the next lowest tab index. We must
// start with the same tab index as ctl, because there can be dups.
while (ctl != this)
if (ctl != this)
{
int targetIndex = ctl._tabIndex;
bool hitCtl = false;
Expand All @@ -6065,20 +6052,26 @@ public Control GetNextControl(Control ctl, bool forward)
if (siblings is null)
{
throw new InvalidOperationException(
string.Format(SR.ControlsPropertyNotSetInGetNextControl, nameof(Control.Controls), parent));
string.Format(SR.ControlsPropertyNotSetInGetNextControl,
nameof(Control.Controls), parent));
}

int siblingCount = siblings.Count;

if (siblingCount == 0)
{
throw new InvalidOperationException(
string.Format(SR.ControlsCollectionShouldNotBeEmptyInGetNextControl, nameof(Control.Controls), parent));
string.Format(SR.ControlsCollectionShouldNotBeEmptyInGetNextControl,
nameof(Control.Controls), parent));
}

// Cycle through the controls in reverse z-order looking for the next lowest tab index. We must
// start with the same tab index as ctl, because there can be dups.
for (int c = siblingCount - 1; c >= 0; c--)
{
Control sibling = siblings[c];
// The logic for this is a bit lengthy, so I have broken it into separate
// clauses:

// We are not interested in ourself.
if (sibling != ctl)
Expand Down Expand Up @@ -6109,18 +6102,54 @@ public Control GetNextControl(Control ctl, bool forward)
}
}

// If we were unable to find a control we should return the control's parent. However, if that parent is us, return
// NULL.
if (found is not null)
{
return found;
ctl = found;
}
else
{
if (parent == this)
{
return null;
}
else
{
// If we don't found any siblings, and the control is a ToolStripItem that hosts a control itself,
// then we shouldn't return its parent, because it would be the same ToolStrip we're currently at.
// Instead, we should return the control that is previous to the current ToolStrip
if (ctl.ToolStripControlHost is not null)
{
return GetNextControl(ctl._parent, forward: false);
}

return parent;
}
}
}

ctl = ctl._parent;
// We found a control. Walk into this control to find the proper child control within it to select.
ControlCollection children = GetControlCollection(ctl);

while (children is not null && children.Count > 0 && (ctl == this || !IsFocusManagingContainerControl(ctl)))
{
Control found = ctl.GetFirstChildControlInTabOrder(forward: false);
if (found is not null)
{
ctl = found;
children = GetControlCollection(ctl);
}
else
{
break;
}
}
}

return ctl == this ? null : ctl;

ControlCollection GetControlCollection(Control control)
static ControlCollection GetControlCollection(Control control)
=> (ControlCollection)control.Properties.GetObject(s_controlsCollectionProperty);
}

Expand Down

0 comments on commit 27b6c5e

Please sign in to comment.