[英]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.