Question

I am using a NotifyIcon from Win Forms to make a systray icon for my WPF C# application.

I have a bug where if the user right clicks the icon for the context menu, they can press Alt-F4 and the icon will disappear from the tray, but the Main WPF application is still running. This is especially a problem when they have "minimized to systray" and the only control of the application is now gone.

Anyone know how to handle this specificially on the systray? I've looked at the NotifyIcon documentation and there isn't anything relating to keypress events.

UPDATE: here's a sample application to show how I'm using the systray and the actual bug. http://cid-e75a75f1a1fbfbb5.office.live.com/self.aspx/.Public/WpfApplication1.zip?sa=221089565

Was it helpful?

Solution 5

OTHER TIPS

First, you can set a hide window in project and activate it in contextMenuStrip2_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) event if e.alt is true.
Second you disable the hide window close, can fix this bug.

eg:

//public partial class HotKeyWin : Window // WindowStyle="ToolWindow"

public partial class NotifyIconWrapper : Component
{
    private HotKeyWin hkeyWin = new HotKeyWin();

    public NotifyIconWrapper()
    {
         hkeyWin.Show();
         hkeyWin.Closing += new CancelEventHandler(hkeyWin_Closing);                
         hkeyWin.Hide();
    }

    void hkeyWin_Closing(object sender, CancelEventArgs e)
    {
         Console.WriteLine("hkeyWin_Closing enter");
         e.Cancel = true;           
    }

    private void contextMenuStrip2_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
         if (e.Alt) hkeyWin.Activate();
    }
}

I know it's pretty old, but as I got the same issue and as I found some reasonable work arround I'm glad to share here.

The solution comes from the event PreviewKeyDown in the WinForm ContextMenuStrip object. One you added this event, just use the following code to stop from AFT-F4 closing only the icon (and its menu) in the tray.

private void myMenuTray_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    if (e.KeyCode == Keys.Menu && e.KeyValue == 18 && e.Alt)
    {
        MessageBox.Show("");
        MessageBox.Show("YOU CAN'T CLOSE HERE WITH ALT-F4");
        return;
    }
}

I know this looks uggly. But it works fine. Up to you to use some confirmation question to look nicer.

Explanations: in any case the ALT-F4 is arriving to the notify object. As in your code you have one 1st MessageBox, the ALT-F4 is captured by this MessageBox which is closed immediatly. The 2nd MessageBox is showed, hence the notify object is not closing.

I've tested the single return (and there is no e.Cancel in there), but each time the notify object is closed while the rest of the application is still in the running processes.

The other good point is you still can work properly with the standard ALT-F4 to close the application (once it's not in the tray!).

Well, I gotta say that was a tricky one, but after some quick testing, I think this will do.

    private void Form1_Load(object sender, EventArgs e)
    {
        this.Activated += new EventHandler(Form1_Activated);
    }

    void Form1_Activated(object sender, EventArgs e)
    {
        string iconPath = "some file system path";
        notifyIcon1.Icon = new Icon(iconPath);
    }

It won't make it so thay you can't make the icon dissappear, but at least when your application get focus, the icon will retrun.

You might also try storing the icon so that you do not need to keep constructing it.

I guess you use the NotifyIcon in a WinFormHost? As the NotifyIcon is simply a control on the Form, you probably have to consume the event in the main form, and if the mainwindow is hidden, ignore the keystroke, like (pseudo):

public mainForm_keypressed(object sender, //eventargs
{
  if(_hidden && //Keystroke detection)
  {
    e.Handled = true;
    return;
  }
}

edit

http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx this might me something worth looking into.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top