我使用标准的WPF ComboBox控件。当弹出窗口打开时,如果用户在外部点击了其他地方,弹出窗口会关闭。但是,如果窗口上有按钮并且用户单击该按钮(弹出窗口仍然打开),则按钮的单击处理程序不会执行。弹出窗口被关闭,但是用户必须再次单击按钮才能触发单击事件。
我知道这是该控件的标准行为。您有任何想法如何绕过此行为吗?谢谢!
我使用标准的WPF ComboBox控件。当弹出窗口打开时,如果用户在外部点击了其他地方,弹出窗口会关闭。但是,如果窗口上有按钮并且用户单击该按钮(弹出窗口仍然打开),则按钮的单击处理程序不会执行。弹出窗口被关闭,但是用户必须再次单击按钮才能触发单击事件。
我知道这是该控件的标准行为。您有任何想法如何绕过此行为吗?谢谢!
EventManager.RegisterClassHandler(typeof(ComboBox), UIElement.PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(FixComboBoxOutClick));
private void FixComboBoxOutClick(object sender, MouseButtonEventArgs e) {
if (sender is ComboBox combo) {
Point comboRelativePoint = Mouse.GetPosition(combo);
if (comboRelativePoint.X < 0 || comboRelativePoint.Y < 0 || comboRelativePoint.X > combo.ActualWidth || comboRelativePoint.Y > combo.ActualHeight) {
UIElement popupContent = combo.FindChild<Popup>(null).Child;
Point popupRelativePoint = Mouse.GetPosition(popupContent);
if (popupRelativePoint.X < 0 || popupRelativePoint.Y < 0 || popupRelativePoint.X > popupContent.RenderSize.Width || popupRelativePoint.Y > popupContent.RenderSize.Height) {
combo.IsDropDownOpen = false;
}
}
}
}
FindChild<T>()
的实现。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
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函数中找到控件后,在该控件上触发鼠标按下事件。
我发现触发事件对于组合框不起作用,所以对于单击它,我只需将IsDropDownOpen设置为true。
我在这里找到了代码并进行了一些修改。
GotMouseCapture="ComboBox_OnGotMouseCapture"
在代码后台:
private void ComboBox_OnGotMouseCapture(object sender, MouseEventArgs e)
{
ComboBox.ReleaseMouseCapture();
}