WinUI3设置亚克力风格窗口调用AddSystemBackdropTarget报错求助
WinUI3 中 DesktopAcrylicController AddSystemBackdropTarget 异常解决
问题场景
在WinUI3中尝试实现亚克力风格窗口,参考WinUI3 Gallery代码调用DesktopAcrylicController.AddSystemBackdropTarget()时抛出异常。使用Visual Studio默认WinUI3模板编写代码,环境为Windows 11 22H2、Windows App Runtime 1.2,已确认窗口DispatcherQueue不为空,尝试过用TryEnqueue()调度任务仍无法解决。
原代码:
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) { // m_window = WindowHelper.CreateWindow(); m_window = new Window(); Frame rootFrame = GetRootFrame(args); // if (m_window.DispatcherQueue != null) // ture DesktopAcrylicController acrylicController = new(); acrylicController.AddSystemBackdropTarget(m_window.As<ICompositionSupportsSystemBackdrop>()); m_window.Activate(); }
解决方案
出现异常的核心原因是窗口初始化不完整(未设置Content)、缺少必要的系统背景配置,以及调用时机不当。以下是修正后的实现步骤:
1. 先为窗口设置Content
Window在未设置Content前,其底层的合成对象可能尚未初始化,导致ICompositionSupportsSystemBackdrop接口实例无效。需先将创建的rootFrame赋值给m_window.Content。
2. 添加SystemBackdropConfiguration配置
DesktopAcrylicController需要通过SystemBackdropConfiguration来获取系统主题、高对比度模式等信息,否则无法正常工作。
3. 正确调用并绑定控制器
确保在窗口初始化完成后调用AddSystemBackdropTarget,并将配置关联到控制器。
修正后的完整代码
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) { m_window = new Window(); Frame rootFrame = GetRootFrame(args); // 先设置窗口Content,确保窗口初始化完成 m_window.Content = rootFrame; // 创建并配置亚克力控制器 if (DesktopAcrylicController.IsSupported()) { var acrylicController = new DesktopAcrylicController(); var configuration = new SystemBackdropConfiguration(); // 绑定窗口的激活状态变化事件,更新配置 m_window.Activated += (s, e) => { configuration.IsActive = e.WindowActivationState != WindowActivationState.Deactivated; }; // 窗口关闭时释放控制器资源 m_window.Closed += (s, e) => acrylicController.Dispose(); // 配置系统主题 configuration.Theme = ((FrameworkElement)m_window.Content).ActualTheme switch { ElementTheme.Dark => SystemBackdropTheme.Dark, ElementTheme.Light => SystemBackdropTheme.Light, _ => SystemBackdropTheme.Default }; // 关联配置并添加目标窗口 acrylicController.SetSystemBackdropConfiguration(configuration); acrylicController.AddSystemBackdropTarget(m_window.As<ICompositionSupportsSystemBackdrop>()); } m_window.Activate(); } private Frame GetRootFrame(LaunchActivatedEventArgs args) { var rootFrame = m_window.Content as Frame; if (rootFrame == null) { rootFrame = new Frame(); rootFrame.NavigationFailed += OnNavigationFailed; if (args.UWPLaunchActivatedEventArgs.PreviousExecutionState == ApplicationExecutionState.Terminated) { // 可在此添加应用状态恢复逻辑 } } return rootFrame; } private void OnNavigationFailed(object sender, NavigationFailedEventArgs e) { throw new Exception("Failed to load Page " + e.SourcePageType.FullName); }
额外说明
- 调用
DesktopAcrylicController.IsSupported()可以提前判断系统是否支持亚克力效果,避免在不支持的环境下抛出异常。 - 窗口关闭时释放控制器资源,可避免内存泄漏。
内容的提问来源于stack exchange,提问作者Howie
相关产品推荐
相关产品推荐

