Search code examples
wpfcomboboxscrollviewer

Handle combobox dropdown when combobox moves


Our WPF application have a ScrollViewer that contains various controls. When a combobox withing this ScrollViewer is opened, and then the user uses the mouse wheel to scroll the ScrollViewer, the combobox control moves, but the dropdown list remains at the same position, which looks awkward.

Is there an easy way to make the combobox close, or the dropdown list's position to update when the ScrollViewer scrolls and change the combobox position?

I know I can handle mouse wheel events, but I have many such situations with a combobox contained within a ScrollViewer, and would love to hear about a better solution.


Solution

  • I handled it by adding the following code in App.xaml.cs:

    EventManager.RegisterClassHandler(typeof(ComboBox), UIElement.GotFocusEvent, new RoutedEventHandler(SetSelectedComboBox));
    EventManager.RegisterClassHandler(typeof(ScrollViewer), UIElement.MouseWheelEvent, new MouseWheelEventHandler(OnMouseWheelEvent));
    
    private static WeakReference<ComboBox> _selectedComboBox;
    
    private static void SetSelectedComboBox(object sender, RoutedEventArgs e)
    {
        _selectedComboBox = new WeakReference<ComboBox>(sender as ComboBox);
    }
    
    // Close dropdown when scrolling with the mouse wheel - QM001866525
    private static void OnMouseWheelEvent(object sender, MouseWheelEventArgs e)
    {
        if (_selectedComboBox == null || Environment.GetEnvironmentVariable("DONT_CLOSE_COMBO_ON_MOUSE_WHEEL") == "1")
        {
            return;
        }
    
        ComboBox combo;
        if (_selectedComboBox.TryGetTarget(out combo) && combo.IsDropDownOpen)
        {
            combo.IsDropDownOpen = false;
        }
    }