我想写一个类似于ComboBox
的控件,我想知道是否有人知道如何检测用户何时在ComboBox
边界外点击。在这种情况下,ComboBox
会关闭它的下拉列表。
答案 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)
您需要创建一个与窗口大小相同的矩形。我这样做是通过使用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那样检测应用程序外部发生的点击。它只会检测应用程序内的点击次数。但坦率地说,无论如何我更喜欢它。