WPF ComboBox:单击弹出窗口外部禁止鼠标单击

时间:2016-06-17 23:25:12

标签: c# wpf combobox behavior dropdown

我使用标准的WPF ComboBox控件。当弹出窗口打开并且用户在外面的某处点击时,弹出窗口将关闭。但是如果窗口上有按钮并且用户点击它(弹出窗口仍然打开),则不会执行按钮的点击处理程序。弹出窗口已关闭,但用户必须再次单击该按钮才能在其上单击事件。

我知道这是此控件的标准行为。您有任何想法如何绕过这种行为?谢谢!

3 个答案:

答案 0 :(得分:1)

您可以为ComboBox DropDownClosed创建一个事件,并使用hittestfunction找到该用户点击的另一个控件。

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;
}

然后在找到该控件后的FilterCallback函数中,在该控件上引发鼠标按下事件。

我发现了raise事件,对组合框没有用,所以点击它,我只是将IsDropDownOpen设置为true。

我在here中找到了代码并对其进行了一些修改。

答案 1 :(得分:0)

您可以尝试在ComboBox获取后立即释放鼠标: 在XAML中的ComboBox属性中:

GotMouseCapture="ComboBox_OnGotMouseCapture"

在代码隐藏中:

private void ComboBox_OnGotMouseCapture(object sender, MouseEventArgs e)
{
    ComboBox.ReleaseMouseCapture();
}

答案 2 :(得分:0)

我使用了一个简单的解决方案: 在PreviewMouseLeftButtonDown事件中,如果鼠标pos在组合框之外,请关闭下拉列表。这将允许其他控件使鼠标单击:

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