You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测WinUI 3中指定DatePicker的Flyout何时打开?

获取DatePicker关联的DatePickerFlyout并监听其打开事件

方案一:通过自定义DatePicker控件模板获取引用

这是最稳定的实现方式,直接从DatePicker的默认模板中拿到Flyout实例:

  1. 在Visual Studio中对目标DatePicker执行「编辑模板」→「编辑副本」操作,生成完整的默认控件模板
  2. 在模板里找到名为DatePickerButton的按钮控件,它的Flyout属性就是关联的DatePickerFlyout
  3. 在代码后台通过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:

  1. 监听DatePicker的Tapped或PointerPressed事件
  2. 事件触发后延迟一小段时间(确保Flyout完成加载),调用VisualTreeHelper.GetOpenPopupsForXamlRoot遍历弹出列表
  3. 筛选出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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:55:13