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

UWP Tab关闭确认对话框未显示问题求助

问题描述

我正在尝试为关闭当前Tab实现一个关闭确认ContentDialog:

  • 预期行为:应用应询问用户是否需要保存,完成后关闭该Tab。
  • 实际行为:对话框未显示。

MainPage(Tab内页面)

public bool IsCloseRequestComplete = false;

public async void RequestClose()
{
    if (TXTFile != null) { try { RAS = await TXTFile.OpenAsync(FileAccessMode.ReadWrite); } catch { } }
    var Value = GetText(REB);
    var SecValue = GetText(RTB);
    if (Value != SecValue)
    {
        //提醒用户保存文件
        ContentDialog ED2 = FileSaveDialog;
        ED2.PrimaryButtonClick += ED2_PrimaryButtonClick;
        ED2.SecondaryButtonClick += ED2_SecondaryButtonClick;
        ED2.CloseButtonClick += ED2_CloseButtonClick;
        try { await ED2.ShowAsync(); } catch { }
        void ED2_PrimaryButtonClick(ContentDialog SenderSec, ContentDialogButtonClickEventArgs DialogEvArgs)
        {
            if (TXTFile != null)
            {
                //后台保存并关闭
                RAS.Dispose();
                SaveCloseBackground();
            }
            else SaveClose();
        }
        void ED2_SecondaryButtonClick(ContentDialog SenderSec, ContentDialogButtonClickEventArgs DialogEvArgs)
        {
            //关闭
            if (TXTFile != null) RAS.Dispose();
            IsCloseRequestComplete = true;
        }
        void ED2_CloseButtonClick(ContentDialog SenderSec, ContentDialogButtonClickEventArgs DialogEvArgs) { }
    }
    else if (Value == SecValue)
    {
        //若文件已保存,关闭页面
        if (TXTFile != null && RAS != null) { try { RAS.Dispose(); } catch { } }
        IsCloseRequestComplete = true;
    }
    return;
}

(SaveClose、SaveCloseBackground、GetText为自定义方法)


TabbedMainPage(Tab宿主页面)

private void TabbedView_TabCloseRequested(TabView sender, TabViewTabCloseRequestedEventArgs args)
{
    MainPage MP = new MainPage();
    MP.RequestClose();
    if (MP.IsCloseRequestComplete == true)
        TabbedView.TabItems.Remove(args.Tab);
    else { MP.RequestClose(); }
    return;
}

问题分析与解决

核心问题1:错误实例化新页面而非获取当前Tab的页面

在TabbedView_TabCloseRequested事件中,你创建了一个全新的MainPage实例,而非获取当前要关闭的Tab对应的已加载页面。新实例的UI未被渲染,调用RequestClose自然不会弹出对话框。

修正代码:

private async void TabbedView_TabCloseRequested(TabView sender, TabViewTabCloseRequestedEventArgs args)
{
    // 获取当前Tab对应的已加载MainPage实例
    if (args.Tab.Content is MainPage currentPage)
    {
        await currentPage.RequestCloseAsync();
        if (currentPage.IsCloseRequestComplete)
        {
            TabbedView.TabItems.Remove(args.Tab);
        }
    }
}

核心问题2:async void导致异步操作无法被等待

RequestClose使用async void,调用方会直接跳过异步逻辑继续执行,此时IsCloseRequestComplete还未被修改,导致Tab关闭逻辑失效。需改为async Task:

修正MainPage的方法:

public bool IsCloseRequestComplete = false;

public async Task RequestCloseAsync()
{
    if (TXTFile != null) 
    { 
        try { RAS = await TXTFile.OpenAsync(FileAccessMode.ReadWrite); } 
        catch { } 
    }
    var Value = GetText(REB);
    var SecValue = GetText(RTB);
    if (Value != SecValue)
    {
        ContentDialog ED2 = FileSaveDialog;
        // 避免重复注册事件(可选优化:初始化时注册或先移除旧事件)
        ED2.PrimaryButtonClick += ED2_PrimaryButtonClick;
        ED2.SecondaryButtonClick += ED2_SecondaryButtonClick;
        ED2.CloseButtonClick += ED2_CloseButtonClick;
        try 
        { 
            await ED2.ShowAsync(); 
        } 
        catch { }

        void ED2_PrimaryButtonClick(ContentDialog SenderSec, ContentDialogButtonClickEventArgs DialogEvArgs)
        {
            if (TXTFile != null)
            {
                RAS.Dispose();
                SaveCloseBackground();
            }
            else 
            {
                SaveClose();
            }
            IsCloseRequestComplete = true; // 保存后标记关闭请求完成
        }
        void ED2_SecondaryButtonClick(ContentDialog SenderSec, ContentDialogButtonClickEventArgs DialogEvArgs)
        {
            if (TXTFile != null) RAS.Dispose();
            IsCloseRequestComplete = true;
        }
        void ED2_CloseButtonClick(ContentDialog SenderSec, ContentDialogButtonClickEventArgs DialogEvArgs) 
        {
            IsCloseRequestComplete = false; // 关闭对话框时取消Tab关闭
        }
    }
    else
    {
        if (TXTFile != null && RAS != null) 
        { 
            try { RAS.Dispose(); } 
            catch { } 
        }
        IsCloseRequestComplete = true;
    }
}

额外优化建议

  • 移除空catch块:吞掉异常会导致调试困难,建议至少记录错误信息。
  • 避免重复注册事件:每次调用RequestCloseAsync都会给FileSaveDialog添加新事件处理程序,多次调用会引发重复执行问题,可在MainPage初始化时一次性注册事件。

内容的提问来源于stack exchange,提问作者Ivirius

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 10:54:35