I have created a wpf application that has a button binded to an ICommand
. When the button is clicked two TaskbarIcon objects are created along with two Toast Notification or BalloonTips as named by the Hardcodet.NotifyIcon.Wpf
Nuget package I use by Philipp Sumi.
The ICommand
code
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),
LeftClickCommand = ShowWindowsCommand,
};
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), {time_passed[1]} minute(s) and {time_passed[2].Substring(0, 2)} seconds ago";
tbi_calculation_status.ShowBalloonTip(title, text, BalloonIcon.None);
}
}
catch (Exception ex)
{
//..
}
finally
{
win_progressbar.Close();
EnableRunCalculationsButton = true;
}
}
As you will notice in the code snippet above I generate two TaskbarIcon
objects:
tbi_during_calculations
tbi_calculation_status
The first is shown to the user during some awaiting Task.Run(() => RunCalculationsMethod();
as shown in my code above. During the calculation of the task, the user can click the TaskbarIcon and call this function ShowWindowsCommand
. After the end of the calculations, the TaskbarIcon object tbi_during_calculations
is disposed along with its Icon.
Then the second TaskBarIcon object tbi_calculation_status
is generated, informing the user whether the calculations were successful or not. Depending on the calculations the BalloonTip would display a different message.
My problem is that when I have already click the application once I get what I want. A single TaskbarIcon. But if I re-click the button a second time without first closing the WPF Application, the TaskBarIcon object tbi_calculation_status
is duplicated without overwriting the previous instance of it. As shown in the image below,
Do you know any smart way to get rid of the first TaskbarIcon object without closing the Application?