We are using a NotifyIcon to alert the user when they receive a new message that needs their attention. In the event that someone else gets to the message first, the notify icon should get hidden again, however I am having a problem with figuring out how to close the balloon from code behind.
My code looks something like this:
myNotifyIcon.ShowBalloonTip(2000, title, message, icon);
I have tried the suggestions found here, but none are suitable.
Using myNotifyIcon.Visible = true does not hide it
Using myNotifyIcon.Visible = false; myNotifyIcon.Visible = true; will hide it, but it also hides the icon in the tray and when it is shown again, it shows up a a different location.
myNotifyIcon.Show(0) is not a valid method
myNotifyIcon.ShowBalloonTip(0) or myNotifyIcon.ShowBalloonTip(1) does not appear to work as the balloon just gets shown and doesn't appear to go away on its own at all.
I read this question about using the WinAPI to find the window and send it a WM_CLOSE message, but I'm not too sure how to do that reliably.
How can I close a NotifyIcon from the code behind?
I've never found a non-hacky way to do that. The documentation says:
Minimum and maximum timeout values are enforced by the operating
system and are typically 10 and 30 seconds, respectively, however this
can vary depending on the operating system. Timeout values that are
too large or too small are adjusted to the appropriate minimum or
maximum value.
Even though this does not specifically address the question of explicitly closing the balloon, it indicates to me that callers of the ShowBalloonTip() method simply do not have complete control over the balloon, once it's been shown.
The best option I've found is one you already mentioned:
myNotifyIcon.Visible = false;
myNotifyIcon.Visible = true;
Not ideal, but it works. Another idea would be to change the message displayed in the balloon to indicate that the previous message is obsolete:
myNotifyIcon.ShowBalloonTip(2000, "Title", "Never mind!", ToolTipIcon.Info);
There is a simple way to do that.
myNotifyIcon.ShowBalloonTip(2000);
myNotifyIcon.visible = true;
this.Hide();
Try this, it'll definitely work 100%.
Related
When displaying a WPF window from an Excel addin, I'm encountering odd behaviour whenever I show it with myWindow.Show() rather than myWindow.ShowDialog(). Thus far everything has worked fine when using the latter. However, it would be nice to be able to display a window such that the user can interact with Excel at the same time - i.e. the behaviour I'd expect from Show().
The problem is that controls in my form start acting very oddly quite quickly. ComboBox dropdowns collapse immediately, and textbox input ends up in whatever cell is selected in the Excel worksheet that's active.
I've noticed that with ShowDialog, Snoop is able to attach to my window as well, whereas with Show, I get an error amounting to "Could not find a PresentationSource to attach to". I'm not, however, completely sure if that's related.
Obviously one solution would be to stop directly showing a WPF window from WinForms; I expect the problem to largely go away if I change my window into a UserControl and chuck it into an ElementHost. However, I'd rather avoid that if I can.
Current code (roughly)
public void DoOpenWindow(Office.IRibbonControl button)
{
var myWindow = new myWindow();
// This hasn't addressed the issue, though may be sensible to include:
//ElementHost.EnableModelessKeyboardInterop(myWindow);
// This *also* didn't work, and essentially set my window to
// be always on top of Excel
//var hwSrc = HwndSource.FromVisual(myWindow );
//var ownerHelper = new WindowInteropHelper(myWindow );
//ownerHelper.Owner = (IntPtr)Globals.ThisAddIn.Application.Hwnd;
// with ShowDialog() this works fine...
myWindow .Show();
}
Current thoughts are:
I'm getting window messages from Excel forwarded to myWindow, some of which it isn't expecting.
Excel is intercepting messages meant for my window (keyboard and mouse), which is probably what ElementHost.EnableModelessKeyboardInterop(myWindow) is intended to solve (but either I'm using it wrong, or it's not the whole solution).
I am using WPF NotifyIcon to create a System Tray service. When I show a messagebox, it shows up for half a second and then disappears immediately without waiting for input.
This kind of situation has happened before, and the usual advice is to use an overload which accepts a Window parameter. However, being a System Tray service, there is no window to use as a parent, and null is not accepted in its place.
Is there any way to make the MessageBox wait for user input short of creating a custom MessageBox window myself?
You don't need to create a proxy window for this. Just add MessageBoxOptions.DefaultDesktopOnly to your message box and it will fire on your desktop without disappearing.
Example
MessageBox.Show("My Message", "Title", MessageBoxButton.OK,
MessageBoxImage.Information, MessageBoxResult.OK,
MessageBoxOptions.DefaultDesktopOnly);
According to the answer here, a workaround is to actually open an invisible window and use that as the parent of the MessageBox:
Window window = new Window()
{
Visibility = Visibility.Hidden,
// Just hiding the window is not sufficient, as it still temporarily pops up the first time. Therefore, make it transparent.
AllowsTransparency = true,
Background = System.Windows.Media.Brushes.Transparent,
WindowStyle = WindowStyle.None,
ShowInTaskbar = false
};
window.Show();
...then open the MessageBox with the appropriate parameter:
MessageBox.Show(window, "Titie", "Text");
...and don't forget to close the window when you're done (possibly on application exit):
window.close();
I tried this and it works well. It's undesirable to have to open an extra window, but it's better than making your own messagebox window just for the sake of making this work.
I'm calling my custom dialog window with this code:
GUI.SLDialog sd = new GUI.SLDialog();
if (sd.ShowDialog() == false)
{
return;
}
But sd.ShowDialog() always returns nothing (i think), because the function breaks, but the waypoint at return; isn't reached.
Dialog is automaticly closing when I add to button:
this.DialogResult = false;//or true
Anybody know what am I doing wrong?
Thanks in advance for your help.C.H.
#edit
This is my SLDialog:
xaml: http://wklej.org/hash/9fb67fb0c7c/
cs: http://wklej.org/hash/16e3ccc6c0d/
I don't think I can tell you much here unless you post the code for the dialog but I do have a suggestion in the mean time.
Since you're already unhappy with the standard dialog boxes and customization is clearly an option why not move towards what people are coming to expect? Instead of your standard dialog why not just create a user control that lays over the rest of your UI and blurs everything out from the background? Much like a jquery dialog box you might see on a web page.
Modality is easier to control since it's just a matter of covering your entire app window with a translucent rectangle and then make the dialog window appear however you want.
Just a suggestion.
I'm trying to add a button to my current project that when pressed will send the window to the back for x-seconds, allow the user to work in other windows, and then automatically come to the front again. By combining How to send a WPF window to the back? and Bring a window to the front in WPF, along with a BackgroundWorker, I was able to get this 99% done. When the button is pressed, the window goes to the back, and returns the specified number of seconds later. The problem is that if I go into another window (Opera, Word, etc), it never return from the back. I tried playing with the flags, but can't seem to get it to work. Is this possible to do? And if so, how?
Thanks!
With a hack it's possible. Just do that:
Topmost = true;
Topmost = false;
and the window should be in front.
Goal:
Don't want the user to use the X mark (upper right of the program's screen) to exit the program.
Problem:
Don't know how to remove that icon that allows user to exit the program?
You can set the ControlBox property to false if you don't want this to display. This will also remove the minimize and maximize buttons, mind you.
I would also ask you to consider why you want to remove this button. Sometimes it makes more sense to override the OnFormClosing method and optionally set Cancel to true under certain conditions (e.g., e.CloseReason == CloseReason.UserClosing).
myForm.ControlBox = false;
Apparently I have to have at least 30 characters in my post, so I will say that I am assuming WinForms since you do not specify yourself. Also note that setting this property to false will remove the minimize and maximize buttons as well.
myform.ControlBox = false;
does it for me
This guy seems to have figured it out:
http://blogs.msdn.com/b/atosah/archive/2007/05/18/disable-close-x-button-in-winforms-using-c.aspx
I used this and its working for me
this.ControlBox = false;