我试图弄清楚如何在鼠标离开时关闭mahapps datetimepicker弹出窗口,而在点击鼠标时不关闭。我已经创建了如下所示的附加行为,它使我获得了99%的收益。
using System;
using System.Reactive.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using MahApps.Metro.Controls;
using Microsoft.Xaml.Behaviors;
using ReactiveUI;
public sealed class CloseDateTimePickerPopUpOnMouseOff : Behavior<DateTimePicker>
{
//Fields
private IDisposable _dateTimePickerLoaded;
private IDisposable _dateTimePickerPopupBorderMouseLeaveSubscription;
private IDisposable _dateTimePickerPopupBorderMouseEnterSubscription;
private IDisposable _dateTimePickerPopupComboBoxGridMouseEnterSubscription;
private IDisposable _dateTimePickerPopupComboBoxGridMouseLeaveSubscription;
protected override void OnAttached()
{
base.OnAttached();
_dateTimePickerLoaded = Observable
.FromEventPattern<RoutedEventArgs>(AssociatedObject, nameof(AssociatedObject.Loaded))
.Take(1)
.ObserveOn(RxApp.MainThreadScheduler)
.Select(_ => AssociatedObject.Template)
.Where(_ => _ != null)
.Subscribe(controlTemplate =>
{
var canClose = true;
var successfullyRetrievedControlTemplateObjects = true;
var dateTimePickerPopup = controlTemplate
.FindName("PART_Popup", AssociatedObject) as Popup;
var dateTimePickerPopupBorder = controlTemplate
.FindName("PART_PopupContainer", AssociatedObject) as Border;
var dateTimePickerPopupHourComboBox = controlTemplate
.FindName("PART_HourPicker", AssociatedObject) as ComboBox;
var dateTimePickerPopupMinuteComboBox = controlTemplate
.FindName("PART_MinutePicker", AssociatedObject) as ComboBox;
var dateTimePickerPopupAmPmComboBox = controlTemplate
.FindName("PART_AmPmSwitcher", AssociatedObject) as ComboBox;
var dateTimePickerPopupComboBoxGrid = controlTemplate
.FindName("PART_ClockPartSelectorsHolder", AssociatedObject) as Grid;
if (dateTimePickerPopup == null
|| dateTimePickerPopupBorder == null
|| dateTimePickerPopupHourComboBox == null
|| dateTimePickerPopupMinuteComboBox == null
|| dateTimePickerPopupComboBoxGrid == null
|| dateTimePickerPopupAmPmComboBox == null)
successfullyRetrievedControlTemplateObjects = false;
if (!successfullyRetrievedControlTemplateObjects) return;
_dateTimePickerPopupBorderMouseEnterSubscription =
dateTimePickerPopupBorder
.Events()
.MouseEnter
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => { canClose = true; });
_dateTimePickerPopupBorderMouseLeaveSubscription =
dateTimePickerPopupBorder
.Events()
.MouseLeave
.Where(_ => canClose && dateTimePickerPopupHourComboBox.IsDropDownOpen == false && dateTimePickerPopupMinuteComboBox.IsDropDownOpen == false && dateTimePickerPopupAmPmComboBox.IsDropDownOpen == false)
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ =>
{
dateTimePickerPopup
.IsOpen = false;
});
_dateTimePickerPopupComboBoxGridMouseEnterSubscription =
dateTimePickerPopupComboBoxGrid
.Events()
.MouseEnter
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => { canClose = false; });
_dateTimePickerPopupComboBoxGridMouseLeaveSubscription =
dateTimePickerPopupComboBoxGrid
.Events()
.MouseLeave
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => { canClose = dateTimePickerPopupBorder.IsMouseOver; });
});
}
protected override void OnDetaching()
{
_dateTimePickerLoaded?.Dispose();
_dateTimePickerPopupBorderMouseLeaveSubscription?.Dispose();
_dateTimePickerPopupComboBoxGridMouseEnterSubscription?.Dispose();
_dateTimePickerPopupComboBoxGridMouseLeaveSubscription?.Dispose();
_dateTimePickerPopupBorderMouseEnterSubscription?.Dispose();
base.OnDetaching();
}
}
Xaml
<controls:DateTimePicker x:Name="StartDateTimePicker"
controls:TextBoxHelper.Watermark="Select a start date"
FontSize="9"
SelectedDateTime="{Binding StartDtm}">
<interactivity:Interaction.Behaviors>
<behaviors:CloseDateTimePickerPopUpOnMouseOff/>
</interactivity:Interaction.Behaviors>
</controls:DateTimePicker>
此方法有效,并在使用组合框小时:分钟:上午/下午时使弹出窗口不关闭,并在鼠标离开实际弹出窗口时关闭。我要解决的一个问题是,当我打开这些组合框之一并将其保持打开状态而不选择任何项目时,然后单击日历中的某个日期以关闭弹出窗口。我尝试将弹出窗口设置为StaysOpen = true,但是没有运气。我可以在重新打开弹出窗口的地方添加一些技巧,但随后您会关闭它并重新打开弹出窗口。