I am working on a .NET WPF project using Visual Studio 2022 and I added tray icon functionality to my app. I also show toast notification whenever my app is minimized to windows tray. I also added a context menu to show up when user right clicks onto tray icon. When toast notification appears and user clicks on the notification ballon, context menu does not open at the first right click event.
I tried to debug and solve the problem. I observe that first right click does not trigger Notifier_MouseDown event. I suppose it is a focus issue that when user clicks onto notification ballon, focus moves somewhere else and thats why it does not trigger at first click. However, I could not figure out how to solve this issue. Any help would be appreciated.
Work so far:
public MainWindow()
{
InitializeComponent();
notifyIcon = new NotifyIcon();
ShowNotifications = true;
notifyIcon.BalloonTipText = TextRes.Get("TrayNotifyBalloonText");
notifyIcon.BalloonTipTitle = TextRes.Get("TrayAppTitle");
notifyIcon.Text = TextRes.Get("TrayAppTitle");
notifyIcon.DoubleClick += new EventHandler(NotifyIcon_Click);
notifyIcon.MouseDown += new MouseEventHandler(Notifier_MouseDown);
notifyIcon.BalloonTipClicked += new EventHandler(NotifyIcon_BalloonTipClicked);
Hide();
menu = (ContextMenu)this.FindResource("NotifierContextMenu");
if (notifyIcon != null)
{
notifyIcon.ShowBalloonTip(60000);
}
}
private void NotifyIcon_BalloonTipClicked(object sender, EventArgs e)
{
Show();
WindowState = m_storedWindowState;
}
private void Window_Closing(object sender, CancelEventArgs e)
{
notifyIcon.BalloonTipText = ResourceHelper.GetResourceText("TrayNotifyBalloonText");
e.Cancel = true;
WindowState = WindowState.Minimized;
Hide();
}
void OnClose(object sender, CancelEventArgs args)
{
notifyIcon.Dispose();
notifyIcon = null;
}
private WindowState m_storedWindowState = WindowState.Normal;
void OnStateChanged(object sender, EventArgs args)
{
if (WindowState == WindowState.Minimized)
{
notifyIcon.BalloonTipText = ResourceHelper.TextRes.Get("TrayNotifyBalloonText");
}
else
m_storedWindowState = WindowState;
}
void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs args)
{
CheckTrayIcon();
}
void NotifyIcon_Click(object sender, EventArgs e)
{
Show();
WindowState = m_storedWindowState;
}
void CheckTrayIcon()
{
ShowTrayIcon(true);
}
void ShowTrayIcon(bool show)
{
if (notifyIcon != null)
notifyIcon.Visible = show;
}
void Notifier_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
menu.IsOpen = true;
IntPtr handle = ((HwndSource)PresentationSource.FromVisual(menu)).Handle;
ApiHelper.SetForegroundWindow(handle);
}
}
private void Menu_Open(object sender, RoutedEventArgs e)
{
Show();
WindowState = m_storedWindowState;
IntPtr handle = ((HwndSource)PresentationSource.FromVisual(this)).Handle;
ApiHelper.SetForegroundWindow(handle);
}
private void Menu_Close(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
<Window.Resources>
<ContextMenu
Focusable="{Binding FocusMenu}"
x:Key="NotifierContextMenu"
StaysOpen="False"
Placement="MousePoint">
<MenuItem Header="Open" Click="Menu_Open"/>
<MenuItem Header="Close" Click="Menu_Close"/>
</ContextMenu>
</Window.Resources>