C# WPF - 单击 Windows Toast 通知按钮时奇怪的主窗口焦点丢失

问题描述 投票:0回答:0

我创建了一个小型 .NET 6 WPF 应用程序来展示这个问题。

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
        }
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var notifier = new Notifier();

            //Send Toast
            notifier.SendToast();

            //Close MainWindow
            Close();
        }
    }

我正在使用 Microsoft.Toolkit.Uwp.Notifications NuGet 包来使用 ToastContentBuilder 发送 Toast 通知。

    public class Notifier
    {
        public Notifier()
        {
            SubscribeToToastCallback();
        }

        public void SendToast()
        {
            var toastContentBuilder = new ToastContentBuilder();
            toastContentBuilder.AddText("Text").AddButton("Test", ToastActivationType.Foreground, "");
            toastContentBuilder.Show();
        }

        private void SubscribeToToastCallback()
        {
            ToastNotificationManagerCompat.OnActivated += toastArgs =>
            {
                //On Toast button click, Show MainWindow activated
                Application.Current.Dispatcher.BeginInvoke(() =>
                {
                    if (Application.Current.MainWindow is null)
                    {
                        Application.Current.MainWindow = new MainWindow();
                        Application.Current.MainWindow.ShowActivated = true;
                    }
                    Application.Current.MainWindow.Show();
                });
            };
        }
    }

我期望发生的事情: Toast 按钮被点击 -> ToastNotificationManagerCompat.OnActivated 被触发 -> 我打开 MainWindow 的代码被执行 -> MainWindow 在前台打开。

实际上发生了什么: Toast 按钮被点击 -> ToastNotificationManagerCompat.OnActivated 被触发 -> 我打开 MainWindow 的代码被执行 -> MainWindow 在前台打开 -> ~0.5 秒后 MainWindow 失去焦点,之前打开的应用程序被激活。

App Gets then Loses Focus

还有一个有趣的例外:

您可以连续重现此场景 10 次,但是如果您单击 toast Body(可交互),它将正确激活我的窗口。此外,它还会使后续通知正确激活窗口,即使您单击了以前尝试导致焦点丢失的按钮。

此外,当 MainWindow 在这种情况下失去焦点时,不会触发 MainWindow.Deactivated 事件(基于 WA_INACTIVE 消息)。所以应用程序不知道 MainWindow 失去了焦点。

我尝试将 ToastActivationType.Foreground 更改为 Background,但没有任何改变。

Show/Focus/Activate() 的所有组合都无济于事。

使用 PInvoke 尝试设置 LockSetForegroundWindow(),没有任何改变。

唯一有效但非常笨拙的是: MainWindow 打开 -> 设置 Topmost = true -> 保持 1 秒(同时 Windows 试图窃取焦点) -> 设置 Topmost = false。

MainWindow.Topmost = true;
Task.Delay(1000).ContinueWith((_) => { Dispatcher.Invoke(() => { MainWindow.Topmost = false; }); });

有谁知道为什么会发生这种情况?它在 0.5 秒后窃取焦点是 Windows 错误吗?还有比我使用 Topmost 找到的解决方案更简单的解决方案吗?

谢谢!

环境:Windows 10 x64 Build 19045

c# wpf windows uwp toast
© www.soinside.com 2019 - 2024. All rights reserved.