[英]Show a message when user clicks outside a window thats launched as ShowDialog
我有示例 Wpf 应用程序,我正在从全屏启动的主 Window 启动 Window。 每当用户在启动的子 Window 之外单击时,我想显示一个消息框。 我实际上提到了这篇文章如何在用户单击外部时关闭 WPF 对话框 Window 。
但问题是,在我的情况下,仅当子 window 在这种情况下关闭时才会出现。 请帮助我如何实现这一目标。 编辑:注意我想 ShowDialog 因为我希望孩子 window 成为阻塞 window。
private void Button_Click(object sender, RoutedEventArgs e)
{
Window w = new Window();
w.Height = 990;
w.Width = 1840;
w.MaxHeight = 990;
w.Width = 1840;
w.WindowStartupLocation = WindowStartupLocation.Manual;
w.Top = this.Height - w.Height;
w.Left = this.Width - w.Width;
w.Deactivated += W_Deactivated;
w.ShowDialog();
}
private void W_Deactivated(object sender, EventArgs e)
{
MessageBox.Show("You clicked out");
}
在这里,我使用使用System.Windows.Input
InputManager PreProcessInput事件来预览鼠标输入事件,由e.StagingItem.Input过滤,在定义的元素( Window
)上生成。
然后,使用element.RestoreBounds.Contains(element.PointToScreen(e.GetPosition(element)))
计算鼠标左键单击的 position。
如果点击是在元素Bounds
之外生成的,则 Window 会显示一条消息,然后关闭(或退出应用程序)。
使用UIElement.CaptureMouse()激活鼠标捕获并使用UIElement.ReleaseMouseCapture在MouseDown
事件上释放。
它或多或少与使用Mouse.Capture()相同。
请注意,您可以单击 Window 控件,但如果您使用其TitleBar
拖动Window
,则不会触发MouseUp
事件(默认情况下它已被吃掉)。
如果这是一个问题,请创建一个逻辑来检测是否在该区域中生成了鼠标事件,并在完成MouseDown
后恢复捕获。
using System.Windows;
using System.Windows.Input;
public partial class YourWindow : Window
{
MouseCapturePreview MouseCaptureHandler;
//(...)
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MouseCaptureHandler = new MouseCapturePreview(this);
//(...)
}
public class MouseCapturePreview
{
public MouseCapturePreview(Window element)
{
InputManager.Current.PreProcessInput += (s, e) => {
if (e.StagingItem.Input is MouseButtonEventArgs)
Handler(s, (MouseButtonEventArgs)e.StagingItem.Input);
};
void Handler(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("Event Received");
if (e.LeftButton == MouseButtonState.Pressed) {
Console.WriteLine("Mouse Released");
element.ReleaseMouseCapture();
Mouse.Capture(element);
if (!element.RestoreBounds.Contains(element.PointToScreen(e.GetPosition(element))))
{
Console.WriteLine("Clicked outside");
MessageBox.Show("You clicked outside, time to close.");
//Application.Current.Shutdown();
element.Close();
}
} else {
Console.WriteLine("Mouse Captured");
element.CaptureMouse();
}
}
}
}
private void Window_Activated(object sender, EventArgs e)
{
Console.WriteLine("Activated");
this.CaptureMouse();
}
}
我找到了另一种方法,完成了几个步骤。 您可以在子视图中创建父事件处理程序。不要调用ShowDialog()
只需调用Dialog()
这是父 window,一旦子 window 打开,您不应该单击此处。
public partial class Parent : Window
{
private void OpenDialog_Clicked(object sender, RoutedEventArgs e)
{
Child child = new Child(this);
child.Show();
}
}
这是子 window,充当对话框并阻止用户单击父级。
public partial class Child : Window
{
private Parent _parent;
public Child(Parent parent)
{
InitializeComponent();
_parent = parent;
parent.PreviewMouseDown += new MouseButtonEventHandler(this.ParentWindow_PreviewMouseDown);
this.Closed += new System.EventHandler(this.Window_Closed);
}
// If you click the parent, you get a message and child window will be top most again
private void ParentWindow_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("na ah");
this.Topmost = true;
}
// If you forget this, you will keep getting that "na ah" message even after closing child window.
private void Window_Closed(object sender, EventArgs e)
{
_parent.PreviewMouseDown -= new MouseButtonEventHandler(ParentWindow_PreviewMouseDown);
}
}
利用
w.Show();
因为较早的一个是模态对话框( Showdialog()
),所以在关闭它之前,您不能进一步 go 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.