From c6f54a538aff66ec51aa95c02e13544c234807d7 Mon Sep 17 00:00:00 2001 From: swethabharathi Date: Tue, 26 May 2026 18:00:07 +0530 Subject: [PATCH 1/3] Fix_Issue_7635 - ContextMenuStrip has erroneous behavior if ToolStripMenuItem item Available=false --- .../ToolStrips/ToolStripDropDownMenu.cs | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) 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..7e4dd64a456 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,11 @@ 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 +788,10 @@ 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 +799,28 @@ internal void ScrollInternal(bool up) UpdateScrollButtonLocations(); } + private ToolStripItem GetNextVisibleItem(int index) + { + for (int i = index + 1; i < Items.Count; i++) + { + if (Items[i].Available) + return Items[i]; + } + + return null; + } + + private ToolStripItem GetPreviousVisibleItem(int index) + { + for (int i = index - 1; i >= 0; i--) + { + if (Items[i].Available) + return Items[i]; + } + + return null; + } + protected override void SetDisplayedItems() { base.SetDisplayedItems(); From 939a38bac93d1cae893d9a780cfa3929cffc1cdd Mon Sep 17 00:00:00 2001 From: swethabharathi Date: Tue, 9 Jun 2026 09:52:07 +0530 Subject: [PATCH 2/3] Fix_Issue_7635 - ContextMenuStrip has erroneous behavior if ToolStripMenuItem item Available=false --- .../ToolStrips/ToolStripDropDownMenu.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) 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 7e4dd64a456..804a86fbc72 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 @@ -799,23 +799,29 @@ internal void ScrollInternal(bool up) UpdateScrollButtonLocations(); } - private ToolStripItem GetNextVisibleItem(int index) + private ToolStripItem? GetNextVisibleItem(int index) { for (int i = index + 1; i < Items.Count; i++) { - if (Items[i].Available) - return Items[i]; + ToolStripItem item = Items[i]; + if (item.Available) + { + return item; + } } return null; } - private ToolStripItem GetPreviousVisibleItem(int index) + private ToolStripItem? GetPreviousVisibleItem(int index) { for (int i = index - 1; i >= 0; i--) { - if (Items[i].Available) - return Items[i]; + ToolStripItem item = Items[i]; + if (item.Available) + { + return item; + } } return null; From 84d6ab53fa632591b888934f72efa09dc3d40ac9 Mon Sep 17 00:00:00 2001 From: swethabharathi Date: Wed, 10 Jun 2026 16:07:09 +0530 Subject: [PATCH 3/3] Fix_Issue_7635 - ContextMenuStrip has erroneous behavior if ToolStripMenuItem item Available=false --- .../Forms/Controls/ToolStrips/ToolStripDropDownMenu.cs | 4 ++++ 1 file changed, 4 insertions(+) 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 804a86fbc72..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 @@ -774,7 +774,9 @@ internal void ScrollInternal(bool up) ToolStripItem itemBottom = Items[_indexOfFirstDisplayedItem]; // We use a delta between the tops, since it takes margin's and padding into account. if (itemTop is not null && itemBottom is not null) + { delta = itemTop.Bounds.Top - itemBottom.Bounds.Top; + } } } else @@ -791,7 +793,9 @@ internal void ScrollInternal(bool up) ToolStripItem itemBottom = GetNextVisibleItem(_indexOfFirstDisplayedItem); // We use a delta between the tops, since it takes margin's and padding into account. if (itemTop is not null && itemBottom is not null) + { delta = itemBottom.Bounds.Top - itemTop.Bounds.Top; + } } }