UWP中点击外部按钮时如何同时隐藏Popup并触发按钮点击事件?
UWP Popup 点击外部按钮同时关闭弹窗并触发按钮事件的解决方案
在UWP中使用Popup并设置IsLightDismissEnabled="True"时,点击外部按钮只会关闭弹窗,按钮的点击事件不会触发。要实现点击外部按钮时同时关闭弹窗并触发按钮事件,可以通过以下两种方法解决:
方法一:监听Popup的Closed事件,手动触发按钮点击
思路:当Popup因点击外部关闭时,在Closed事件中判断点击位置是否落在目标按钮上,若符合则手动调用按钮的点击逻辑。
步骤:
- 修改XAML,给Button2添加
x:Name并绑定Popup的Closed事件:
<Grid> <Button Width="100" Height="50" Click="Button_Click" Content="Button 1"></Button> <Popup x:Name="popup" IsLightDismissEnabled="True" Closed="Popup_Closed"> <Grid Width="200" Height="200" Background="AliceBlue"></Grid> </Popup> <Button x:Name="button2" Width="100" Height="50" Margin="300 0 0 0" Content="Button 2" Click="Button2_Click"></Button> </Grid>
- 后台代码实现逻辑:
private Point? _lastClickPosition; protected override void OnPointerPressed(PointerRoutedEventArgs e) { base.OnPointerPressed(e); // 记录点击的屏幕位置 _lastClickPosition = e.GetCurrentPoint(this).Position; } private void Popup_Closed(object sender, object e) { if (_lastClickPosition == null) return; // 将屏幕坐标转换为Button2的本地坐标 var localPoint = button2.TransformToVisual(this).TransformPoint((Point)_lastClickPosition); // 判断点击位置是否在Button2范围内 if (button2.ActualWidth >= localPoint.X && localPoint.X >= 0 && button2.ActualHeight >= localPoint.Y && localPoint.Y >= 0) { // 手动触发Button2的点击逻辑 Button2_Click(button2, null); } _lastClickPosition = null; } private void Button_Click(object sender, RoutedEventArgs e) { popup.IsOpen = true; } private async void Button2_Click(object sender, RoutedEventArgs e) { var dialog = new MessageDialog("Button2被点击了"); await dialog.ShowAsync(); }
方法二:禁用LightDismiss,手动处理外部点击关闭Popup
思路:关闭Popup的IsLightDismissEnabled,通过监听页面的PointerPressed事件,判断点击是否在Popup外部,若符合则关闭Popup,同时保留按钮点击事件的正常触发。
步骤:
- 修改XAML中的Popup属性:
<Grid> <Button Width="100" Height="50" Click="Button_Click" Content="Button 1"></Button> <Popup x:Name="popup" IsLightDismissEnabled="False"> <Grid Width="200" Height="200" Background="AliceBlue"></Grid> </Popup> <Button Width="100" Height="50" Margin="300 0 0 0" Content="Button 2" Click="Button2_Click"></Button> </Grid>
- 后台代码添加点击监听逻辑:
protected override void OnPointerPressed(PointerRoutedEventArgs e) { base.OnPointerPressed(e); if (!popup.IsOpen) return; // 获取点击位置相对于Popup的坐标 var popupPoint = popup.Child.TransformToVisual(this).TransformPoint(e.GetCurrentPoint(this).Position); // 判断点击是否在Popup外部 if (popupPoint.X < 0 || popupPoint.X > popup.Child.ActualWidth || popupPoint.Y < 0 || popupPoint.Y > popup.Child.ActualHeight) { popup.IsOpen = false; } } private void Button_Click(object sender, RoutedEventArgs e) { popup.IsOpen = true; } private async void Button2_Click(object sender, RoutedEventArgs e) { var dialog = new MessageDialog("Button2被点击了"); await dialog.ShowAsync(); }
两种方法均可实现需求:点击Button2时,Popup关闭的同时触发Button2的点击事件。方法一更贴近原有LightDismiss的默认行为,方法二则完全自定义控制逻辑,可根据实际场景选择。
内容的提问来源于stack exchange,提问作者Tom Xue
相关产品推荐
相关产品推荐

