From 5c8c6ad530d0ee27ec8b9dce256f0abd6530446b Mon Sep 17 00:00:00 2001 From: Alex Gradov <144119594+MORTEM3845@users.noreply.github.com> Date: Sun, 25 Oct 2026 11:24:13 +0300 Subject: [PATCH] Fix Calendar mouse capture preventing dialog close on first click --- .../CalendarAssist.cs | 30 +++++++++++++++++++ .../Themes/MaterialDesignTheme.Calendar.xaml | 1 + 2 files changed, 31 insertions(+) diff --git a/src/MaterialDesignThemes.Wpf/CalendarAssist.cs b/src/MaterialDesignThemes.Wpf/CalendarAssist.cs index 8bcf3d1a40..abd1bbe38e 100644 --- a/src/MaterialDesignThemes.Wpf/CalendarAssist.cs +++ b/src/MaterialDesignThemes.Wpf/CalendarAssist.cs @@ -9,6 +9,36 @@ public enum CalendarOrientation } public static class CalendarAssist { + #region ReleaseMouseCaptureOnMouseUp + /// Identifies the attached property that releases a CalendarItem's mouse capture after a left mouse button release. + public static readonly DependencyProperty ReleaseMouseCaptureOnMouseUpProperty = DependencyProperty.RegisterAttached( + "ReleaseMouseCaptureOnMouseUp", typeof(bool), typeof(CalendarAssist), new PropertyMetadata(false, OnReleaseMouseCaptureOnMouseUpChanged)); + + /// Gets whether the CalendarItem releases its mouse capture on mouse-up. + public static bool GetReleaseMouseCaptureOnMouseUp(DependencyObject element) => (bool)element.GetValue(ReleaseMouseCaptureOnMouseUpProperty); + /// Sets whether the CalendarItem releases its mouse capture on mouse-up. + public static void SetReleaseMouseCaptureOnMouseUp(DependencyObject element, bool value) => element.SetValue(ReleaseMouseCaptureOnMouseUpProperty, value); + + private static void OnReleaseMouseCaptureOnMouseUpChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is not CalendarItem calendarItem) + return; + + if ((bool)e.NewValue) + calendarItem.AddHandler(Mouse.MouseUpEvent, new MouseButtonEventHandler(OnCalendarItemMouseUp), true); + else + calendarItem.RemoveHandler(Mouse.MouseUpEvent, new MouseButtonEventHandler(OnCalendarItemMouseUp)); + } + + private static void OnCalendarItemMouseUp(object sender, MouseButtonEventArgs e) + { + // Calendar's day button handles MouseUp, skipping CalendarItem.OnMouseUp. + // Release only this item's capture, after the day button has finished selection. + if (e.ChangedButton == MouseButton.Left && sender is CalendarItem { IsMouseCaptured: true } calendarItem) + calendarItem.ReleaseMouseCapture(); + } + #endregion + #region Header Visibility public static readonly DependencyProperty IsHeaderVisibleProperty = DependencyProperty.RegisterAttached( "IsHeaderVisible", typeof(bool), typeof(CalendarAssist), new PropertyMetadata(true)); diff --git a/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.Calendar.xaml b/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.Calendar.xaml index 1b7001d991..2bdb0dbd1e 100644 --- a/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.Calendar.xaml +++ b/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.Calendar.xaml @@ -335,6 +335,7 @@