每次在 WPF 应用程序中单击按钮时都会创建 TaskbarIcon

问题描述

我创建了一个 wpf 应用程序,它有一个绑定到 ICommand 的按钮。单击按钮时,会创建两个 TaskbarIcon 对象以及两个 Toast Notification 或 BalloonTips,这些对象由我使用的 Philipp Sumi 使用的 Hardcodet.NotifyIcon.Wpf Nuget 包命名。

ICommand 代码

public ICommand RuncalculationCommand_Approach2
{
    get { return new DelegateCommand<object>(ExecutesqlAsync); }
}
private async void ExecutesqlAsync(object obj)
{
    //1. TaskBar During Calculations (during calculations)
    Stream iconStream_one = Application.GetResourceStream(new Uri("pack://application:,/TestApp;component/Assets/loading.ico")).Stream;
    Stream iconStream_two = Application.GetResourceStream(new Uri("pack://application:,/TestApp;component/Assets/loading.ico")).Stream;

    TaskbarIcon tbi_during_calculations = new TaskbarIcon
    {
        Icon = new Icon(iconStream_one),LeftClickCommand = ShowWindowsCommand,};

    //2. TaskBar Calculations Status (calculations completed-Failed-stopped)
    TaskbarIcon tbi_calculation_status = new TaskbarIcon
    {
        Icon = new Icon(iconStream_two),};

    try
    {
        //Notify the user that calculations have already started
        tbi_during_calculations.Visibility = Visibility.Visible;
        string title_startup = "Calculations Started";
        string text_startup = "You can Now minimize the window and return back once the calculations finish.";
        tbi_during_calculations.ShowBalloonTip(title_startup,text_startup,BalloonIcon.None);

        DateTime timestamp_start = DateTime.Now;

        await Task.Run(() => RuncalculationsMethod(object_progressbar,"LOG_DETAILS",1,true,getconnectionstring,CatchErrorExceptionMessage,this.CancellationTokenSource.Token),this.CancellationTokenSource.Token);
        
        string[] time_passed = DateTime.Now.Subtract(timestamp_start).ToString().Split(@":");

        //The code below is executed after the Task is completed or if it's cancelled.
        List<SucessfulCompletion> reportsucessfulcompletion = new List<SucessfulCompletion>();
        reportsucessfulcompletion = CheckLogsFailSuccessprocedure(sqlServerConnectionDetails());

        tbi_during_calculations.Icon.dispose();
        tbi_during_calculations.dispose();
        
        if (reportsucessfulcompletion[0].Result == 0)
        {
            //Add Balloon tip
            tbi_calculation_status.Visibility = Visibility.Visible;
            string title = "Calculations Completed";
            string text = $"Calculations have been completed in \n{time_passed[0]} hour(s),{time_passed[1]} minute(s) and {time_passed[2].Substring(0,2)} seconds";
            tbi_calculation_status.ShowBalloonTip(title,text,BalloonIcon.None);
        }
        else
        {
            //Add Balloon tip
            tbi_calculation_status.Visibility = Visibility.Visible;
            string title = "Calculations Failed";
            string text = $"Calculations stopped \n{time_passed[0]} hour(s),2)} seconds ago";
            tbi_calculation_status.ShowBalloonTip(title,BalloonIcon.None);
        }
    }
    catch (Exception ex)
    {
        //..
    }
    finally
    {
        win_progressbar.Close();
        EnableRuncalculationsButton = true;
    }
}

正如您在上面的代码片段中所注意到的,我生成了两个 TaskbarIcon 对象:

  • tbi_during_calculations
  • tbi_calculation_status

一个在等待 Task.Run(() => RuncalculationsMethod(); 期间向用户显示,如我上面的代码所示。在计算任务的过程中,用户可以点击TaskbarIcon,调用这个函数ShowWindowsCommand。计算结束后,TaskbarIcon 对象 tbi_during_calculations 与其图标一起被处理。

然后生成第二个TaskBarIcon对象tbi_calculation_status通知用户计算是否成功。根据计算结果,BalloonTip 会显示不同的消息。

我的问题是,一旦我得到了我想要的东西,我就已经点击了应用程序。单个任务栏图标。但是,如果我在没有先关闭 WPF 应用程序的情况下再次单击该按钮,则 TaskBarIcon 对象 tbi_calculation_status 将被复制,而不会覆盖它的前一个实例。如下图所示,

enter image description here

您知道在不关闭应用程序的情况下摆脱第一个 TaskbarIcon 对象的聪明方法吗?

解决方法

您必须隐藏(处置)tbi_calculation_status 实例(与tbi_during_calculations 相同)

为每次按钮点击创建 tbi_calculation_status 图标,因此您将在第二次点击按钮时获得两个 tbi_calculation_status 图标(第三次点击三个,以此类推)

在一个应用程序的系统托盘中有两个图标有点奇怪。 您可以使用一个图标,但在计算开始/停止时调整工具提示。