如何检测WinUI 3中指定DatePicker的Flyout何时打开?
获取DatePicker关联的DatePickerFlyout并监听其打开事件
方案一:通过自定义DatePicker控件模板获取引用
这是最稳定的实现方式,直接从DatePicker的默认模板中拿到Flyout实例:
- 在Visual Studio中对目标DatePicker执行「编辑模板」→「编辑副本」操作,生成完整的默认控件模板
- 在模板里找到名为
DatePickerButton的按钮控件,它的Flyout属性就是关联的DatePickerFlyout - 在代码后台通过
GetTemplateChild方法获取该按钮,进而拿到Flyout并绑定事件
XAML模板示例(核心部分):
<DatePicker x:Name="MyDatePicker"> <DatePicker.Template> <ControlTemplate TargetType="DatePicker"> <!-- 省略模板其他冗余内容 --> <Button x:Name="DatePickerButton" Flyout="{StaticResource DatePickerFlyout}"> <!-- 按钮默认内容 --> </Button> <!-- 省略模板其他冗余内容 --> </ControlTemplate> </DatePicker.Template> </DatePicker>
后台代码示例:
protected override void OnApplyTemplate() { base.OnApplyTemplate(); var datePickerButton = GetTemplateChild("DatePickerButton") as Button; if (datePickerButton?.Flyout is DatePickerFlyout flyout) { flyout.Opening += DatePickerFlyout_Opening; flyout.Opened += DatePickerFlyout_Opened; } } private void DatePickerFlyout_Opening(object sender, object e) { // Flyout即将打开时的业务逻辑 } private void DatePickerFlyout_Opened(object sender, object e) { // Flyout已打开时的业务逻辑 }
方案二:结合点击事件与GetOpenPopupsForXamlRoot实时获取
若不想修改控件模板,可利用DatePicker的触发时机配合API获取已打开的Flyout:
- 监听DatePicker的
Tapped或PointerPressed事件 - 事件触发后延迟一小段时间(确保Flyout完成加载),调用
VisualTreeHelper.GetOpenPopupsForXamlRoot遍历弹出列表 - 筛选出
DatePickerFlyout类型的实例并绑定事件
后台代码示例:
public MainPage() { InitializeComponent(); MyDatePicker.Tapped += MyDatePicker_Tapped; } private async void MyDatePicker_Tapped(object sender, TappedRoutedEventArgs e) { // 延迟100ms确保Flyout已完成打开 await Task.Delay(100); var popups = VisualTreeHelper.GetOpenPopupsForXamlRoot(MyDatePicker.XamlRoot); foreach (var popup in popups) { if (popup.Child is DatePickerFlyoutPresenter presenter && presenter.Flyout is DatePickerFlyout flyout) { flyout.Opening += DatePickerFlyout_Opening; flyout.Opened += DatePickerFlyout_Opened; // 解绑点击事件避免重复绑定 MyDatePicker.Tapped -= MyDatePicker_Tapped; break; } } }
注意事项
- 方案一的自定义模板方式可靠性更高,不受系统性能或Flyout加载时机影响,优先推荐
- 方案二的延迟时间需根据实际场景调整,避免因系统卡顿导致获取失败
- 页面卸载时记得解绑已绑定的Flyout事件,防止内存泄漏
内容的提问来源于stack exchange,提问作者aturnbul
相关产品推荐
相关产品推荐

