C# NotifyIcon stays in tray after the Balloon Tip has been closed - c#

after the Ballon Tip of my NotifyIcon has been close the icon still stays in tray.
It vanishes only when I hover it with my mouse cursor.
I have a class Notification.cs which has one component - NotifyIcon.
I call it from my Console Application as I only want to show the notification when certain conditions are fulfilled.
Some code:
how I call the notification from within my program:
Notification not = new Notification("Error occured, do this or that", "Some error", System.Windows.Forms.ToolTipIcon.Error);
not.getIcon().ShowBalloonTip(1000);
the notification class:
public Notification(string baloonTipText, string baloonTipTitle, System.Windows.Forms.ToolTipIcon icon) : this()
{
this.icon.Visible = true;
this.icon.BalloonTipText = baloonTipText;
this.icon.BalloonTipTitle = baloonTipTitle;
this.icon.BalloonTipIcon = icon;
}
public System.Windows.Forms.NotifyIcon getIcon()
{
return this.icon;
}
private void icon_BalloonTipClosed(object sender, EventArgs e)
{
this.icon.Visible = false;
this.icon.Dispose();
}
Any ideas?

Because you're running in a console application, your icon_BalloonTipClosed handler will not be invoked when the balloon tip is closed (no message pump). You will need to call Dispose manually either as your application exits or set a timer (System.Threading.Timer, System.Windows.Forms.Timer will not work) with a timeout longer than the balloon tip's timeout. e.g.:
timer = new Timer(state => not.getIcon().Dispose(), null, 1200, Timeout.Infinite);

using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
namespace ShowToolTip
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btBallonToolTip_Click(object sender, EventArgs e)
{
ShowBalloonTip();
this.Hide();
}
private void ShowBalloonTip()
{
Container bpcomponents = new Container();
ContextMenu contextMenu1 = new ContextMenu();
MenuItem runMenu = new MenuItem();
runMenu.Index = 1;
runMenu.Text = "Run...";
runMenu.Click += new EventHandler(runMenu_Click);
MenuItem breakMenu = new MenuItem();
breakMenu.Index = 2;
breakMenu.Text = "-------------";
MenuItem exitMenu = new MenuItem();
exitMenu.Index = 3;
exitMenu.Text = "E&xit";
exitMenu.Click += new EventHandler(exitMenu_Click);
// Initialize contextMenu1
contextMenu1.MenuItems.AddRange(
new System.Windows.Forms.MenuItem[] { runMenu, breakMenu, exitMenu });
// Initialize menuItem1
this.ClientSize = new System.Drawing.Size(0, 0);
this.Text = "Ballon Tootip Example";
// Create the NotifyIcon.
NotifyIcon notifyIcon = new NotifyIcon(bpcomponents);
// The Icon property sets the icon that will appear
// in the systray for this application.
string iconPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + #"\setup-icon.ico";
notifyIcon.Icon = new Icon(iconPath);
// The ContextMenu property sets the menu that will
// appear when the systray icon is right clicked.
notifyIcon.ContextMenu = contextMenu1;
notifyIcon.Visible = true;
// The Text property sets the text that will be displayed,
// in a tooltip, when the mouse hovers over the systray icon.
notifyIcon.Text = "Morgan Tech Space BallonTip Running...";
notifyIcon.BalloonTipText = "Morgan Tech Space BallonTip Running...";
notifyIcon.BalloonTipTitle = "Morgan Tech Space";
notifyIcon.ShowBalloonTip(1000);
}
void exitMenu_Click(object sender, EventArgs e)
{
this.Close();
}
void runMenu_Click(object sender, EventArgs e)
{
MessageBox.Show("BallonTip is Running....");
}
}
}

Related

ContextMenuStrip in c# tray application not reacting correctly when in expanded icon window

I have made a tray application with an icon that opens a ContextMenuStrip on Icon Click. I have three ToolStripMenuItem that can be clicked.
The Tray Application is working fine as long as the icon is visible directly. However if I have to click on the chevron to expand the non visible tray icons, I run into one Problem.
I can open the Menu by click on the Item. If I click on one of the ToolStripMenuItems the Tray-Menu goes into the Background of the Expanded Tray Icons and cannot be clicked anymore. How can I prevent this?
It seems the background is capturing the click rather then the openend form.
Here is the code for the Menu.
class Menu
{
private static ContextMenuStrip contextMenuStrip;
private static NotifyIcon notifyIcon1 = new NotifyIcon();
public Menu()
{
notifyIcon1.Icon = new Icon("icon.ico");
notifyIcon1.Text = "icon";
contextMenuStrip = new ContextMenuStrip();
ToolStripItem stripItem0 = new ToolStripMenuItem("open");
contextMenuStrip.Items.AddRange(new ToolStripItem[] { stripItem0 });
ToolStripItem stripItem1 = new ToolStripMenuItem("stop");
stripItem1.Click += new EventHandler(ToggleTracking);
contextMenuStrip.Items.AddRange(new ToolStripItem[] { stripItem1 });
ToolStripItem line = new ToolStripSeparator();
contextMenuStrip.Items.AddRange(new ToolStripItem[] { line });
ToolStripItem stripItem2 = new ToolStripMenuItem("close");
stripItem2.Click += new EventHandler(Close);
contextMenuStrip.Items.AddRange(new ToolStripItem[] { stripItem2 });
notifyIcon1.ContextMenuStrip = contextMenuStrip;
//notifyIcon1.ContextMenu = contextMenu1;
notifyIcon1.Click += new EventHandler(IconClick);
notifyIcon1.Visible = true;
}
private void ToggleTracking(object Sender, EventArgs e)
{
ToolStripMenuItem stripItem1 = (ToolStripMenuItem)contextMenuStrip.Items[1];
if (stripItem1.Text == "stop")
{
stripItem1.Text = "restart";
Batch.StopTimer();
}
else
{
stripItem1.Text = "stop";
Batch.RestartTimer();
}
}
private void Close(object Sender, EventArgs e)
{
Application.Exit();
}
private void IconClick(object Sender, EventArgs e)
{
Control strip = Sender as Control;
if (contextMenuStrip.Visible)
{
contextMenuStrip.Hide();
}
else
{
contextMenuStrip.Show(Cursor.Position);
}
}
}
I had to use the BringToFront method like this.
{
contextMenuStrip.Show(Cursor.Position);
contextMenuStrip.BringToFront();
}
https://msdn.microsoft.com/de-de/library/system.windows.forms.control.bringtofront(v=vs.110).aspx

NotifyIcon hides app from taskbar. How to avoid that?

I have an application that goes to system tray when I minimize it. I created a notify icon to handle some secondary options for the app using right click from mouse using that notify icon.
But I would like the application not to disappear from task bar when I minimize it and mantain the notify icon on system tray.
Is there any way to acomplish thtat?
EDIT: When I minimize the application, I use the Hide() command to use the NotifyIcon. But I want it to remain on task bar.
See code here:
private void MainWindow_OnStateChanged(object sender, EventArgs e)
{
if (WindowState != WindowState.Minimized) return;
Hide();
ShowInTaskbar = true;
if (notifyIcon != null)
notifyIcon.ShowBalloonTip(2000);
}
Note: This NotifyIcon is embeded on a WPF container programatically like this:
DrawNotifyIcon();
private void DrawNotifyIcon()
{
try
{
string source = Path.GetDirectoryName(Assembly.GetAssembly(typeof(MainWindow)).CodeBase);
string tmpSource = source + #"\Resources\mainico.ico";
tmpSource = tmpSource.Replace(#"file:\", "");
// notify Icon
notifyIcon = new NotifyIcon
{
BalloonTipTitle = Cultures.Resources.Title,
BalloonTipText = Cultures.Resources.NotifyIconExecuting,
BalloonTipIcon = ToolTipIcon.Info,
Icon = new System.Drawing.Icon(tmpSource)
};
notifyIcon.DoubleClick += notifyIcon_DoubleClick;
notifyIcon.Click += notifyIcon_Click;
notifyIcon.MouseUp += notifyIcon_MouseUp;
// Create ContextMenu
contextMenu = new ContextMenuStrip();
contextMenu.Closing += contextMenu_Closing;
// Exit item
menuItemExit = new ToolStripMenuItem
{
Text = Cultures.Resources.Exit,
Image = Cultures.Resources.close
};
menuItemExit.Click += menuItemExit_Click;
// Restore item
menuItemRestore = new ToolStripMenuItem
{
Text = Cultures.Resources.Restore,
Image = Cultures.Resources.restore1
};
menuItemRestore.Click += menuItemRestore_Click;
// Active or inactive log
menuItemActive = new ToolStripMenuItem
{
Text = Cultures.Resources.On,
Image = Cultures.Resources.green,
Checked = true
};
menuItemActive.Click += menuItemActive_Click;
menuItemActive.CheckStateChanged += menuItemActive_CheckStateChanged;
// Order of appearance of ContextMenu items
contextMenu.Items.Add(menuItemActive);
contextMenu.Items.Add("-");
contextMenu.Items.Add(menuItemRestore);
contextMenu.Items.Add(menuItemExit);
notifyIcon.ContextMenuStrip = contextMenu;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Any idea on how to keep both icons for WPF?
Well, Its not possible to show forms in taskbar which is in hidden state. Still you can forcefully minimized the form. try below modified code :
private void MainWindow_OnStateChanged(object sender, EventArgs e)
{
if (WindowState != WindowState.Minimized) return;
this.ShowInTaskbar = true;
if (notifyIcon != null)
notifyIcon.ShowBalloonTip(2000);
this.WindowState = FormWindowState.Minimized;
}

Save window state when application in tray

I have an app that minimizes to the system tray by clicking on "close" button and I want to save it's state (position, all elements (comboboxes, textboxes) with their values, etc).
Now I wrote this code, but it creates a new window from tray (instead of recovering the old one, with its parameters):
# app.xaml.cs:
this.ShutdownMode = ShutdownMode.OnExplicitShutdown;
// create a system tray icon
var ni = new System.Windows.Forms.NotifyIcon();
ni.Visible = true;
ni.Icon = QuickTranslator.Properties.Resources.MainIcon;
ni.DoubleClick +=
delegate(object sender, EventArgs args)
{
var wnd = new MainWindow();
wnd.Visibility = Visibility.Visible;
};
// set the context menu
ni.ContextMenu = new System.Windows.Forms.ContextMenu(new[]
{
new System.Windows.Forms.MenuItem("About", delegate
{
var uri = new Uri("AboutWindow.xaml", UriKind.Relative);
var wnd = Application.LoadComponent(uri) as Window;
wnd.Visibility = Visibility.Visible;
}),
new System.Windows.Forms.MenuItem("Exit", delegate
{
ni.Visible = false;
this.Shutdown();
})
});
How I can modify this code for my problem?
When you hold a reference to your `MainWindow´ then you can simple call Show() again after closing it. Closing the Window will simply hide it and calling Show again will restore it.
private Window m_MainWindow;
ni.DoubleClick +=
delegate(object sender, EventArgs args)
{
if(m_MainWindow == null)
m_MainWindow = new MainWindow();
m_MainWindow.Show();
};
If you´re sure that the MainWidnow is your Applications primary Window then you can also use this:
ni.DoubleClick +=
delegate(object sender, EventArgs args)
{
Application.MainWindow.Show();
};
I would prefer the first variant since it´s explicit.

Opening a ContextMenu from a ToolStripMenuItem

I am trying to mimic the behavior of, for example, Windows Explorer and how the Favorites items can launch a context menu.
I currently am using:
contextMenu.Show((sender as ToolStripMenuItem).GetCurrentParent().PointToScreen(e.Location));
This occurs in the MouseDown event of the ToolStripMenuItem. The problem is that the menu closes immediately after right-click, and I don't know any way to suspend it while the context menu is open.
I've tried deriving from ToolStripMenuItem and overriding the MouseDown/MouseUp but I can't figure out how to keep it open on click.
Is there a good way of doing this?
This is what I've had luck with, it's a bit more direct:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
void MenuItemContext(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) return;
ToolStripMenuItem mID = (ToolStripMenuItem)sender;
ContextMenu tsmiContext = new ContextMenu();
MenuItem Item1 = new MenuItem();
MenuItem Item2 = new MenuItem();
Item1.Text = "Item1";
Item2.Text = "Item2";
tsmiContext.MenuItems.Add(Item1);
tsmiContext.MenuItems.Add(Item2);
Item1.Click += new EventHandler(Item1_Click);
Item2.Click += new EventHandler(Item2_Click);
hndPass = mID.Text;
tsmiContext.Show(menuStrip1, menuStrip1.PointToClient(new Point(Cursor.Position.X, Cursor.Position.Y)));
}
private String hndPass;
void Item1_Click(object sender, EventArgs e)
{
MenuItem mID = (MenuItem)sender;
MessageBox.Show("You clicked " + mID.Text + " in the context menu of " + hndPass);
}
void Item2_Click(object sender, EventArgs e)
{
MenuItem mID = (MenuItem)sender;
MessageBox.Show("You clicked " + mID.Text + " in the context menu of " + hndPass); ;
}
}
One way that you could accomplish this is by using the ToolStripDropDown control to host a ListBox inside of the ToolStripDropDown.
This may require some tweaking regarding the AutoClose behavior, but it should get you started:
First in your main form, add the following line to your ToolStripDropDropDown item
toolStripDropDownButton1.DropDown = new CustomListDropDown();
Then create a custom drop down class as follows:
public class CustomListDropDown : ToolStripDropDown
{
private ContextMenuStrip contextMenuStrip1;
private ToolStripMenuItem toolStripMenuItem1;
private ToolStripMenuItem toolStripMenuItem2;
private ToolStripMenuItem toolStripMenuItem3;
private System.ComponentModel.IContainer components;
public ListBox ListBox { get; private set; }
public CustomListDropDown()
{
InitializeComponent();
this.ListBox = new ListBox() { Width = 200, Height = 600 };
this.Items.Add(new ToolStripControlHost(this.ListBox));
this.ListBox.ContextMenuStrip = contextMenuStrip1;
this.ListBox.MouseDown += new MouseEventHandler(ListBox_MouseDown);
contextMenuStrip1.Closing += new ToolStripDropDownClosingEventHandler(contextMenuStrip1_Closing);
//add sample items
this.ListBox.Items.Add("Item1");
this.ListBox.Items.Add("Item2");
this.ListBox.Items.Add("Item3");
this.ListBox.Items.Add("Item4");
}
void contextMenuStrip1_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
this.Close();
this.AutoClose = true;
}
void ListBox_MouseDown(object sender, MouseEventArgs e)
{
this.AutoClose = false;
this.ListBox.SelectedIndex = this.ListBox.IndexFromPoint(e.Location);
}
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem();
this.contextMenuStrip1.SuspendLayout();
this.SuspendLayout();
//
// contextMenuStrip1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem1,
this.toolStripMenuItem2,
this.toolStripMenuItem3});
this.contextMenuStrip1.Name = "contextMenuStrip1";
//
// contextMenuStrip1.ContextMenuStrip
//
this.contextMenuStrip1.Size = new System.Drawing.Size(181, 48);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(180, 22);
this.toolStripMenuItem1.Text = "toolStripMenuItem1";
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(180, 22);
this.toolStripMenuItem2.Text = "toolStripMenuItem2";
//
// toolStripMenuItem3
//
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
this.toolStripMenuItem3.Size = new System.Drawing.Size(180, 22);
this.toolStripMenuItem3.Text = "toolStripMenuItem3";
//
// CustomListDropDown
//
this.Size = new System.Drawing.Size(2, 4);
this.contextMenuStrip1.ResumeLayout(false);
this.ResumeLayout(false);
}
}
In my tests this worked reasonably well. Let me know how it goes.
As ContextMenuStrip is derived from ToolStripDropDown, you could do this:
private ContextMenuStrip CopyToContextMenu(ToolStripMenuItem mnuItemSource)
{
var mnuContextDestination = new ContextMenuStrip();
//Move itens from ToolStripMenuItem to ContextMenuStrip
while (mnuItemSource.DropDown.Items.Count > 0)
{
mnuContextDestination.Items.Add(mnuItemSource.DropDown.Items[0]);
}
//Put ContextMenuStrip in ToolStripMenuItem using DropDown property
mnuItemSource.DropDown = mnuContextDestination;
return mnuContextDestination;
}

Creating balloon tooltip in C#

Can i know how can i make a popup bubble message in my application coded in C#.
Like example, when i start my application, it'll popup saying "Welcome to UbuntuSE App".
And yea, The popup is not the message box popup, it's the popup in the traymenu.
Something similar to this:
PS,
If i'm not wrong, this is called Balloon Tooltips. But how can i use this in my codes.
If you're using Winforms you have the NotifyIcon class. This object has a ShowBalloonTip method which will show a balloon tip:
var icon = new NotifyIcon();
icon.ShowBalloonTip(1000, "Balloon title", "Balloon text", ToolTipIcon.None)
you must be looking for the Notify Icon Control
another CodeProject Example
here is a full example in MSDN
You can use the NotifyIcon control that's part of .NET 2.0 System.Windows.Forms.
Check : Using the NotifyIcon control
From the msdn,
NotifyIcon : Specifies a component that creates an
icon in the notification area. This
class cannot be inherited.
NotifyIcon.BalloonTipIcon
You have to set the property "icon" or it won't pop up
NotifyIcon ballon = new NotifyIcon();
ballon.Icon = SystemIcons.Application;//or any icon you like
ballon.ShowBalloonTip(1000, "Balloon title", "Balloon text", ToolTipIcon.None)
using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
namespace ShowToolTip
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btBallonToolTip_Click(object sender, EventArgs e)
{
ShowBalloonTip();
this.Hide();
}
private void ShowBalloonTip()
{
Container bpcomponents = new Container();
ContextMenu contextMenu1 = new ContextMenu();
MenuItem runMenu = new MenuItem();
runMenu.Index = 1;
runMenu.Text = "Run...";
runMenu.Click += new EventHandler(runMenu_Click);
MenuItem breakMenu = new MenuItem();
breakMenu.Index = 2;
breakMenu.Text = "-------------";
MenuItem exitMenu = new MenuItem();
exitMenu.Index = 3;
exitMenu.Text = "E&xit";
exitMenu.Click += new EventHandler(exitMenu_Click);
// Initialize contextMenu1
contextMenu1.MenuItems.AddRange(
new System.Windows.Forms.MenuItem[] { runMenu, breakMenu, exitMenu });
// Initialize menuItem1
this.ClientSize = new System.Drawing.Size(0, 0);
this.Text = "Ballon Tootip Example";
// Create the NotifyIcon.
NotifyIcon notifyIcon = new NotifyIcon(bpcomponents);
// The Icon property sets the icon that will appear
// in the systray for this application.
string iconPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + #"\setup-icon.ico";
notifyIcon.Icon = new Icon(iconPath);
// The ContextMenu property sets the menu that will
// appear when the systray icon is right clicked.
notifyIcon.ContextMenu = contextMenu1;
notifyIcon.Visible = true;
// The Text property sets the text that will be displayed,
// in a tooltip, when the mouse hovers over the systray icon.
notifyIcon.Text = "Morgan Tech Space BallonTip Running...";
notifyIcon.BalloonTipText = "Morgan Tech Space BallonTip Running...";
notifyIcon.BalloonTipTitle = "Morgan Tech Space";
notifyIcon.ShowBalloonTip(1000);
}
void exitMenu_Click(object sender, EventArgs e)
{
this.Close();
}
void runMenu_Click(object sender, EventArgs e)
{
MessageBox.Show("BallonTip is Running....");
}
}
}
Thanks for the info!
Made something like this and worked!
private void NotifyBaloon(string text, string tooltip, string title, bool show)
{
notifyIconMain.Text = text;
notifyIconMain.BalloonTipText = tooltip;
notifyIconMain.BalloonTipTitle = title;
if (show)
notifyIconMain.ShowBalloonTip(1000);
}

Categories

Resources