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
相关产品推荐
相关产品推荐

