WPF - Combobox如何知道何时关闭下拉菜单

时间:2009-09-15 05:22:08

标签: .net wpf combobox controls

我想写一个类似于ComboBox的控件,我想知道是否有人知道如何检测用户何时在ComboBox边界外点击。在这种情况下,ComboBox会关闭它的下拉列表。

2 个答案:

答案 0 :(得分:2)

您可以使用文本框和弹出窗口定义自己的自定义控件和控件模板。然后覆盖控件的OnApplyTemplate方法,并使用以下命令查找弹出窗口:

var popup = this.GetTemplateChild("PART_Popup") as Popup;

现在,您可以通过将其IsOpen属性设置为true或false来决定何时显示或隐藏弹出窗口。

要了解用户是否点击了您的其他部分,只需在控件的父级(控件初始化代码中的某个位置)订阅PreviewMouseDown事件:

var parent = VisualTreeHelper.GetParent(this) as UIElement;
if(parent != null) {
    parent.PreviewMouseDown += MouseDownHandler;
}

现在,只要用户点击控件容器内的任何位置,您就会收到通知。您还可以递归使用VisualTreeHelper.GetParent(...)来获取根元素(例如窗口),直到它返回null。

弹出窗口不在同一个可视化树中,因此如果您想知道用户何时在弹出窗口内单击,您需要为弹出窗口的根元素定义鼠标事件处理程序。

答案 1 :(得分:2)

很多年前,我在Silverlight的早期版本中遇到了同样的问题。我检查了控件模板并反编译了Microsoft代码,发现他们在整个窗口中使用了一个不可见的叠加来检测点击。 WPF comboBox似乎没有相同的工作方式,但您可以遵循Silverlight模式。

您需要创建一个与窗口大小相同的矩形。我这样做是通过使用RowSpan来覆盖保存整个应用程序的主Grid。您还可以将高度/宽度绑定到窗口高度/宽度。有十几种方法可以做到这一点,只需让它填满你的整个窗口。为矩形提供填充颜色为白色且不透明度为0.它确实需要填充颜色才能工作,但是如果Opacity = 0,则用户将看不到它。出于调试目的,您可以将其赋予红色和不透明度.25。

<Rectangle x:Name="fullScreenOverlay" Grid.RowSpan="3" Opacity="0" Fill="White" Visibility="Collapsed" MouseDown="FullScreenOverlay_OnMouseDown" />

其中一个关键部分是将Rectangle放在XAML的底部处,以便它在任何其他XAML控件之上呈现。

当你打开类似控件的ComboBox时,将此矩形设置为Visible,以便它可以检测到click / MouseDown。

private void NotificationButton_Click(object sender, RoutedEventArgs e)
{
    fullScreenOverlay.Visibility = Visibility.Visible;
    notificationPopup.Visibility = Visibility.Visible;
}

当您检测到点击时,将矩形设置回折叠并关闭您的ComboBox,如弹出窗口。一切都完成了。

private void FullScreenOverlay_OnMouseDown(object sender, MouseButtonEventArgs e)
{
    fullScreenOverlay.Visibility = Visibility.Collapsed;
    notificationPopup.Visibility = Visibility.Collapsed;
}

这不会像Microsoft ComboBox那样检测应用程序外部发生的点击。它只会检测应用程序内的点击次数。但坦率地说,无论如何我更喜欢它。

相关问题