public static class OutsideCloser { public static readonly DependencyProperty CloseProperty = DependencyProperty.RegisterAttached( "Close", typeof(bool), typeof(OutsideCloser), new FrameworkPropertyMetadata(PropertyChangedCallback)); [AttachedPropertyBrowsableForType(typeof(Window))] public static void SetClose(Window target, bool value) { target.SetValue(CloseProperty, value); } [AttachedPropertyBrowsableForType(typeof(Window))] public static bool GetClose(Window target) { return (bool)target.GetValue(CloseProperty); } private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is Window window) { window.Loaded += Window_Loaded; window.Closed += Window_Closed; window.LostMouseCapture += Window_LostMouseCapture; } } private static void Window_LostMouseCapture(object sender, MouseEventArgs e) { var window = (Window)sender!; Mouse.Capture(window, CaptureMode.SubTree); } private static void Window_Closed(object? sender, EventArgs e) { var window = (Window)sender!; window.LostMouseCapture -= Window_LostMouseCapture; window.Closed -= Window_Closed; window.Loaded -= Window_Loaded; window.RemoveHandler(Mouse.PreviewMouseDownOutsideCapturedElementEvent, (MouseButtonEventHandler)HandleClickOutsideOfControl); window.ReleaseMouseCapture(); } private static void Window_Loaded(object sender, RoutedEventArgs e) { var window = (Window)sender; Mouse.Capture(window, CaptureMode.SubTree); window.AddHandler(Mouse.PreviewMouseDownOutsideCapturedElementEvent, (MouseButtonEventHandler)HandleClickOutsideOfControl); } private static void HandleClickOutsideOfControl(object sender, MouseButtonEventArgs e) { var window = (Window)sender; var owner = window.Owner; var point = e.MouseDevice.GetPosition(owner); if (point.X >= 0 && point.X <= owner.ActualWidth && point.Y >= 0 && point.Y <= owner.ActualHeight) { window.Close(); } } }