WPF ComboBox: click outside of popup suppress mouse click

前端 未结 3 1613
[愿得一人]
[愿得一人] 2021-01-21 17:15

I use a standard WPF ComboBox control. When popup is opened and user clicks somewhere outside, popup is closed. But if there is button on the window and user clicks on it (with

相关标签:
3条回答
  • 2021-01-21 17:53

    You can create an event for ComboBox DropDownClosed and with the hittestfunction, find the other control that the user has clicked.

    private void ComboBox_DropDownClosed(object sender, EventArgs e)
    {
        Point m = Mouse.GetPosition(this);
        VisualTreeHelper.HitTest(this, this.FilterCallback, this.ResultCallback, new PointHitTestParameters(m));
    }
    
    private HitTestFilterBehavior FilterCallback(DependencyObject o)
    {
        var c = o as Control;
        if ((c != null) && !(o is MainWindow))
        {
            if (c.Focusable)
            {
                if (c is ComboBox)
                {
                    (c as ComboBox).IsDropDownOpen = true;
                }
                else
                {
                    var mouseDevice = Mouse.PrimaryDevice;
                    var mouseButtonEventArgs = new MouseButtonEventArgs(mouseDevice, 0, MouseButton.Left)
                    {
                        RoutedEvent = Mouse.MouseDownEvent,
                        Source = c
                    };
                    c.RaiseEvent(mouseButtonEventArgs);
                }
    
                return HitTestFilterBehavior.Stop;
            }
        }
        return HitTestFilterBehavior.Continue;
    }
    
    private HitTestResultBehavior ResultCallback(HitTestResult r)
    {
        return HitTestResultBehavior.Continue;
    }
    

    Then in the FilterCallback function after finding that control, raise the mouse down event on that control.

    I found the raise event, does not work on comboboxes so for clicking that, I simply set the IsDropDownOpen to true.

    I found the code in here and modified it a little.

    0 讨论(0)
  • 2021-01-21 17:58

    You can try to release the mouse capture right after the ComboBox gets one: In your's ComboBox properties in XAML:

    GotMouseCapture="ComboBox_OnGotMouseCapture"
    

    And in code-behind:

    private void ComboBox_OnGotMouseCapture(object sender, MouseEventArgs e)
    {
        ComboBox.ReleaseMouseCapture();
    }
    
    0 讨论(0)
  • 2021-01-21 17:59

    I used an easy solution: In the PreviewMouseLeftButtonDown event, if the mouse pos is outside the combobox, close the dropdown. This will allow other control to get the mouse click:

    Dim p = Mouse.GetPosition(combo)
    If p.X < 0 OrElse p.Y < 0 OrElse p.X > combo.Width OrElse p.Y > combo.Height Then
         cmb.IsDropDownOpen = False
    End If
    
    0 讨论(0)
提交回复
热议问题