diff --git a/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownMenu.cs b/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownMenu.cs index 84f0a338aa7..47e156f3f2e 100644 --- a/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownMenu.cs +++ b/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDownMenu.cs @@ -751,7 +751,7 @@ internal void ScrollInternal(bool up) // calling this to get ScrollWindowEx. In actuality it does nothing // to change the display rect! - int delta; + int delta = 0; if (_indexOfFirstDisplayedItem == -1 || _indexOfFirstDisplayedItem >= Items.Count) { Debug.Fail("Why wasn't 'UpdateScrollButtonStatus called'? We don't have the item to scroll by"); @@ -770,10 +770,13 @@ internal void ScrollInternal(bool up) } else { - ToolStripItem itemTop = Items[_indexOfFirstDisplayedItem - 1]; + ToolStripItem itemTop = GetPreviousVisibleItem(_indexOfFirstDisplayedItem); ToolStripItem itemBottom = Items[_indexOfFirstDisplayedItem]; // We use a delta between the tops, since it takes margin's and padding into account. - delta = itemTop.Bounds.Top - itemBottom.Bounds.Top; + if (itemTop is not null && itemBottom is not null) + { + delta = itemTop.Bounds.Top - itemBottom.Bounds.Top; + } } } else @@ -787,9 +790,12 @@ internal void ScrollInternal(bool up) } ToolStripItem itemTop = Items[_indexOfFirstDisplayedItem]; - ToolStripItem itemBottom = Items[_indexOfFirstDisplayedItem + 1]; + ToolStripItem itemBottom = GetNextVisibleItem(_indexOfFirstDisplayedItem); // We use a delta between the tops, since it takes margin's and padding into account. - delta = itemBottom.Bounds.Top - itemTop.Bounds.Top; + if (itemTop is not null && itemBottom is not null) + { + delta = itemBottom.Bounds.Top - itemTop.Bounds.Top; + } } } @@ -797,6 +803,34 @@ internal void ScrollInternal(bool up) UpdateScrollButtonLocations(); } + private ToolStripItem? GetNextVisibleItem(int index) + { + for (int i = index + 1; i < Items.Count; i++) + { + ToolStripItem item = Items[i]; + if (item.Available) + { + return item; + } + } + + return null; + } + + private ToolStripItem? GetPreviousVisibleItem(int index) + { + for (int i = index - 1; i >= 0; i--) + { + ToolStripItem item = Items[i]; + if (item.Available) + { + return item; + } + } + + return null; + } + protected override void SetDisplayedItems() { base.SetDisplayedItems();