I am working on a .NET WPF project using Visual Studio 2022 and I added tray icon functionality to my app. Everything works fine except when tray icon is right clicked context menu opened but when user clicks outside ContextMenu it does not disappear. I tried to add "StaysOpen" property to false but it did not work. What should I do to solve this? here is my code:
public partial class MainWindow : Window
{
public NotifyIcon m_notifyIcon;
public MainWindow()
{
InitializeComponent();
m_notifyIcon = new System.Windows.Forms.NotifyIcon();
m_notifyIcon.BalloonTipText = "The app has been minimised. Click the tray icon to show.";
m_notifyIcon.BalloonTipTitle = "The App";
m_notifyIcon.Text = "The App";
m_notifyIcon.Icon = new System.Drawing.Icon("48x48_active.ico");
m_notifyIcon.DoubleClick = new EventHandler(m_notifyIcon_Click);
m_notifyIcon.MouseDown = new MouseEventHandler(notifier_MouseDown);
Hide();
if (m_notifyIcon != null)
m_notifyIcon.ShowBalloonTip(2000);
CheckTrayIcon();
}
void OnClose(object sender, CancelEventArgs args)
{
m_notifyIcon.Dispose();
m_notifyIcon = null;
}
private WindowState m_storedWindowState = WindowState.Normal;
void OnStateChanged(object sender, EventArgs args)
{
if (WindowState == WindowState.Minimized)
{
Hide();
if (m_notifyIcon != null)
m_notifyIcon.ShowBalloonTip(2000);
}
else
m_storedWindowState = WindowState;
}
void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs args)
{
CheckTrayIcon();
}
void m_notifyIcon_Click(object sender, EventArgs e)
{
Show();
WindowState = m_storedWindowState;
}
void CheckTrayIcon()
{
ShowTrayIcon(true);
}
void ShowTrayIcon(bool show)
{
if (m_notifyIcon != null)
m_notifyIcon.Visible = show;
}
void notifier_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
ContextMenu menu = (ContextMenu)this.FindResource("NotifierContextMenu");
menu.IsOpen = true;
}
}
private void Menu_Open(object sender, RoutedEventArgs e)
{
Show();
WindowState = m_storedWindowState;
}
private void Menu_Close(object sender, RoutedEventArgs e)
{
System.Windows.Application.Current.Shutdown();
}
}
<Window x:Class="TrayApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TrayApp"
mc:Ignorable="d"
StateChanged="OnStateChanged" IsVisibleChanged="OnIsVisibleChanged"
Title="MainWindow" Height="450" Width="800">
<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>
<Grid>
</Grid>
</Window>
CodePudding user response:
What should I do to solve this?
Activate the ContextMenu
using the Win32 SetForegroundWindow
API:
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
void notifier_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
ContextMenu menu = (ContextMenu)this.FindResource("NotifierContextMenu");
menu.IsOpen = true;
IntPtr handle = ((HwndSource)PresentationSource.FromVisual(menu)).Handle;
SetForegroundWindow(handle);
}
}