From 6b91fc3f33893d803798481e5b64ebfae6e3a82d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Sat, 11 Oct 2025 11:19:09 +0100 Subject: [PATCH] Workaround for dismissing navigation menu --- ILSpy/Controls/MainToolBar.xaml.cs | 33 ++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/ILSpy/Controls/MainToolBar.xaml.cs b/ILSpy/Controls/MainToolBar.xaml.cs index 877796e96..4cf45a419 100644 --- a/ILSpy/Controls/MainToolBar.xaml.cs +++ b/ILSpy/Controls/MainToolBar.xaml.cs @@ -16,6 +16,8 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; +using System.ComponentModel; using System.Composition; using System.Linq; using System.Windows; @@ -117,6 +119,14 @@ namespace ICSharpCode.ILSpy.Controls var dropDownPanel = new StackPanel { Orientation = Orientation.Horizontal }; + var dropDownToggle = new ToggleButton { + Style = ThemeManager.Current.CreateToolBarToggleButtonStyle(), + Content = "▾", + Padding = new Thickness(0), + MinWidth = 0, + Margin = new Thickness(0, 0, 2, 0) + }; + var contextMenu = new ContextMenu { PlacementTarget = dropDownPanel, Tag = command @@ -126,15 +136,6 @@ namespace ICSharpCode.ILSpy.Controls toolbarItem.ContextMenu = contextMenu; toolbarItem.ContextMenuOpening += (_, _) => PrepareParameterList(contextMenu); - - var dropDownToggle = new ToggleButton { - Style = ThemeManager.Current.CreateToolBarToggleButtonStyle(), - Content = "▾", - Padding = new Thickness(0), - MinWidth = 0, - Margin = new Thickness(0, 0, 2, 0) - }; - dropDownToggle.Checked += (_, _) => { PrepareParameterList(contextMenu); contextMenu.Placement = PlacementMode.Bottom; @@ -147,6 +148,20 @@ namespace ICSharpCode.ILSpy.Controls BindingOperations.SetBinding(dropDownToggle, IsEnabledProperty, new Binding(nameof(IsEnabled)) { Source = toolbarItem }); + // When the toggle button is checked, clicking it to uncheck will dimiss the menu first + // which unchecks the toggle button via binding above and the click is used to open it again. + // This is a workaround to ignore the click to uncheck the already unchecked toggle button. + // We have to ensure the dismissing click is on the toggle button, otherwise the flag + // will not get cleared and menu will not open next time. + Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(contextMenu, (_, e) => { + var point = e.GetPosition(dropDownToggle); + dropDownToggle.Tag = dropDownToggle.InputHitTest(point); + }); + dropDownToggle.PreviewMouseLeftButtonDown += (_, e) => { + e.Handled = dropDownToggle.Tag != null; + dropDownToggle.Tag = null; + }; + dropDownPanel.Children.Add(toolbarItem); dropDownPanel.Children.Add(dropDownToggle); return dropDownPanel;