I try to show a balloon tip like the one in the screenshot:
First I created a notifyIcon
Then I added this code to the Form1_Load function:
private void Form1_Load(object sender, EventArgs e)
{
notifyIcon1.Visible = true;
notifyIcon1.Icon = SystemIcons.Exclamation;
notifyIcon1.BalloonTipTitle = "Balloon Tip Title";
notifyIcon1.BalloonTipText = "Balloon Tip Text.";
notifyIcon1.BalloonTipIcon = ToolTipIcon.Error;
notifyIcon1.ShowBalloonTip(10000);
}
All I get is a little icon, and If I hover over it then i see the name of the notify icon.
I also tried this notifyIcon1.ShowBalloonTip(10000, "Text", "Title", ToolTipIcon.Warning); but then nothing happens.
I noticed in the function description of ShowBalloonTip, that the parameter "timeout" is deprecated from windows vista on, so what should I do instead?
PS: I run it on windows 10 64bit.
UPDATE 1/3:
I just created a fresh project, the balloon tip does not show either.
Maybe a setting in my OS blocks these messages?
UPDATE 2/3:
I downloaded the project from #pisi1001 but I get the same behaviour.
So I think it must be either a bug in windows 10, a wrong setting or group policy.
However like the next screenshots shows, the app is even allowed to show notifications:
UPDATE 3/3:
I noticed that you can even configure deeper if you double click on the setting, e.g. on "WindowsFormsApp1" from the last screenshot.
After I activated the setting in the red box in the last screenshot (which is basically saying "Show Notifications in the Info Center") I get at least notifications in the info center now:
This must be a Windows 10 Bug.
LAST UPDATE: A few weeks passed since I asked this question, now it seems to work and I am not sure why. Maybe Microsoft fixed it after I reported it to them.
Related
I use the .NET Framework System.Windows.Forms.NotifyIcon class to display a tray icon and tray notifications. When I call ShowBalloonTip on its instance, first the previously displayed notification displays again, then it hides, and only after a while does the expected one is displayed. It seems that historical notifications are displayed first unless I remove them manually from the notification center.
What can I do programmatically to prevent showing the historical notifications again?
Here's how I initialize the notify icon:
notifyIcon.Icon = Properties.Resources.tray_icon;
notifyIcon.Visible = true;
notifyIcon.BalloonTipTitle = Language.TrayMessageTitle;
Here's how I show the toast:
notifyIcon.BalloonTipIcon = icon;
notifyIcon.BalloonTipText = message;
notifyIcon.ShowBalloonTip(0);
The icon is either ToolTipIcon.Error or ToolTipIcon.Info, and I don't show a toast with the same icon twice, so they always toggle. But this does not seem to matter.
The timeout param is 0, because it's not used since Windows Vista.
The toast is displayed as a result of an application state change, not as a result of a user action like clicking.
So I decided to stick with disposing the notify icon instance and recreating it every time I display a toast notification. I don't think it's fine, but I couldn't find a better solution.
I also dispose the notify icon on application shutdown to clean the notification center from previously displayed notifications. Otherwise, the last one displays first when another application displays a toast.
I can't get a form to remain on top, in .net
I have checked How to make form always on top in Application and the answer there mentions form1.TopLevel = true; and I've checked How to make a window always stay on top in .Net? and it says Form.ActiveForm.TopMost so i've tried Form.ActiveForm.TopMost = true; and this.TopMost = true;
private void Form1_Load(object sender, EventArgs e)
{
this.TopLevel = true; //default anyway
Form.ActiveForm.TopMost = true;
this.TopMost = true;
}
But as you can see, a notepad window or any window can cover it.
Added
I have tried every suggestion made so far.
In response to Han's advice, "Of all the possible places to set TopMost property, the Load event is the worst. It should be set in the constructor, so the window gets created top-most right away. Or it should be set after it is visible, so after the Load event. Use the constructor. ". I tried putting those lines in the constructor.
public Form1()
{
InitializeComponent();
this.TopLevel = true; //default anyway
//Form.ActiveForm.TopMost = true; (commented to prevent a System.InvalidOperationException, presumably the form isn't yet active at this stage)
this.TopMost = true;
}
And the the other two suggestions, from others-
I tried setting the Form's TopMost field in the designer to True.
And running the EXE directly rather than just clicking play in visual studio.
Same issue.
And if you find that hard to believe, i've taken a 1min video here showing just that. https://screencast-o-matic.com/watch/cbXXrw2oTN
A potentially useful comment was mentioned..
Steve comments - "OK something definitively odd is happening here. I have tried to create a simple topmost form using linqpad and at the first run I get your same behavior. At the second run though everything works as expected."
A workaround, is this, following on from Han's point to put not put it in Load. Load is indeed too early. I've been finding that (at least on the system with the issue), The Constructor is also too early. I find that putting it in the Shown event, works.
One possible solution to this, is to run this patch, https://support.microsoft.com/en-us/help/2587473/topmost-windows-are-not-always-in-the-topmost-position-in-windows-7-or But be warned, if you want to uninstall it, I have some doubts whether it uninstalls correctly. And it's also not clear to me whether the patch is working or working sporadically. It likely works but it's hard for me to tell.
One commenter thought it's just my system, though that's not the case, as Steve ran into the same issue the first time he ran it. I find it may be most prone to happen after windows restarts, So, the program is running very fresh. But I find that putting that code in the Shown event, is fine and the form stays on top.
I tried instead of TopMost=true, using SetWindowPos, to set the window on top, I tried it fairly early like in the constructor, and late, like in the Shown event or on a button click, and I found it was fine in the Shown event or on a button click. So the issue was related to the TopMost=true line, or SetWindowPos line, firing too early, prior to the window it is setting appearing.
When calling SetWindowPos later one can use either this.Handle or GetForegroundWindow(), the former is easier as it's native. When calling it earlier one must use this.Handle. And using this.TopMost=true avoids all winAPI calls completely.
So in short, you could try the patch, though note that it might not uninstall right.. Or you can try the workaround of putting this.TopMost=true in the Shown event of the form.
On Windows 10, the ShowBalloonTip method of NotifyIcon NEVER shows the balloon tip. This would appear to have something to do with Windows itself.
If I go to Settings > System > Notifications & actions > and find my running app (vshost32.exe in debug mode) and click on it, then turn on Show notifications in the action center, I can clearly see the balloon tip messages being added to the notifications, but never a balloon tip.
I assume this is a problem with Windows 10.
My NotifyIcon is VISIBLE
my_icon.ShowBalloonTip("Title", "Message", BalloonIcon.Info);
On my computer with Windows 10 version 1803, go to Settings > System > Notifications & actions, and turn on "Get notifications from apps and other senders".
The ballontips from my WPF app will show up.
Found the problem - was simple: Quiet Hours was turned on in the notification center and this was preventing the balloon tips.
Turn off Focus Assist. If you are using second screen, turn off "When I'm duplicating my display" option. My settings is like that:
I've fixed the problem by adding icon property. If this property isn't set, the baloontip won`t be shown. Here's example of my code:
var notify = new NotifyIcon();
notify.Visible = true;
notify.Icon = new System.Drawing.Icon(#"D:\Users\User\Desktop\some.ico");
int code = new Random().Next(1000, 9999);
notify.ShowBalloonTip(500, "code", $"{code}", ToolTipIcon.Info);
Neither of these solved my issue :(
But by accident I fixed it! My problem was I had my project configured for 32-bit on a 64-bit platform and for whatever reason they only show up when when I run the project for Any CPU (64-bit in this case)!!
Hopefully that helps some of you, it was a real mystery for me...
(I also posted this answer here because these are duplicate questions)
Change the Solution Configuration "Debug mode to Release mode" with X64 or X32 Solution platform. It will start work.
public static NotifyIcon trayIcon;
trayIcon = new NotifyIcon();
trayIcon.Icon = new Icon("Images/Test.ico");
trayIcon.Visible = true; trayIcon.Text=Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName);
ContextMenu contextMenu1 = new ContextMenu();
contextMenu1.MenuItems.Add("Menu2", Menu2_Event);
contextMenu1.MenuItems.Add("Menu3", Menu3_event);
contextMenu1.MenuItems.Add("Exit", Close_Click);
trayIcon.ContextMenu = contextMenu1;
trayIcon.BalloonTipText = "Hi Test";
trayIcon.ShowBalloonTip(1000);
Just for reference, as #rmirabelle wrote in the question "My NotifyIcon is VISIBLE". This is actually important.
If the notification icon is not visible in the systray, the BalloonTips won't show up either.
Possible sources for invisibility are:
Visible property = false
No icon is set for the NotifyIcon object
Universal app does not allow to remove or disable the close button it seems. We can hide it by going full screen. But when moving cursor over it, brings title bar back. Is there any way to remove the close button?
Reason : I am working on screen time. After allowed time gets over, I want to block the screen. I should remove close button so that user cant get over my app.
Edit : Removing close button wont help completely. It is a part of work. I am just asking how to remove it.
In Windows 10 version 1703 (build 10.0.15063) and beyond, you can prevent the app from closing, using the SystemNavigationManagerPreview class.
Add this to your app manifest:
<Capabilities>
<rescap:Capability Name="confirmAppClose" />
</Capabilities
You need to have the rescap namespace at the Package element:
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
In the constructor of your main form, add:
var sysNavMgr = SystemNavigationManagerPreview.GetForCurrentView();
sysNavMgr.CloseRequested += OnCloseRequested;
OnCloseRequested can be implemented as follows:
private void OnCloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e)
{
var deferral = e.GetDeferral();
e.Handled = true;
deferral.Complete();
}
With current released API, we are able to customize the color of these three buttons in title bar. But there is no property or method could be used to disable or remove these buttons.
In UWP, we can use ApplicationView.TitleBar | titleBar property to get the title bar like following:
ApplicationViewTitleBar titleBar = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().TitleBar;
This property's type is ApplicationViewTitleBar. It only has several properties that can customize the button's color like:
titleBar.ButtonBackgroundColor = Windows.UI.Colors.White;
titleBar.ButtonForegroundColor = Windows.UI.Colors.White;
titleBar.ButtonHoverBackgroundColor = Windows.UI.Colors.White;
titleBar.ButtonHoverForegroundColor = Windows.UI.Colors.White;
titleBar.ButtonInactiveBackgroundColor = Windows.UI.Colors.White;
titleBar.ButtonInactiveForegroundColor = Windows.UI.Colors.White;
titleBar.ButtonPressedBackgroundColor = Windows.UI.Colors.White;
titleBar.ButtonPressedForegroundColor = Windows.UI.Colors.White;
Using these properties may make the close button invisible like:
However this won't actually hide these buttons. Users can still minimize or maximize the app and when the pointer is over the top right corner, they will still see the close button.
From Windows 8.1, if we want users to use only an application and do nothing else including closing the application, we can use Kiosk Mode. For more info, please see Enable Kiosk Mode in Windows 8.1 and Set up a kiosk on Windows 10 Pro, Enterprise, or Education. However this won't meet your requirement as you want to block the screen after allowed time gets over.
So UWP may not be the best choice for your requirement. You may try to implement it with classic desktop apps.
in App.Xaml.cs add this code :
// Collapse Title bar
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
Window.Current.SetTitleBar(null);
ApplicationView view = ApplicationView.GetForCurrentView();
view.TryEnterFullScreenMode();
C++ Version
// COLLAPSE THE TITLE BAR
Windows::ApplicationModel::Core::CoreApplication::GetCurrentView()->TitleBar->ExtendViewIntoTitleBar = true;
Window::Current->SetTitleBar(nullptr);
Windows::UI::ViewManagement::ApplicationView^ view = Windows::UI::ViewManagement::ApplicationView::GetForCurrentView();
view->TryEnterFullScreenMode();
i am using this code under my form1_load
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(5000, "Welcome", "Hello " + User, ToolTipIcon.Info);
I even checked my registery and the value was 1. Why is the baloon not showing?
I do have a icon form my notify icon. and it is showing up. The Baloon is not though!
Looks like you forgot to set the Icon for it like this
notifyIcon1.Icon = SystemIcons.Exclamation;
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(5000, "Welcome", "Hello " + User, ToolTipIcon.Info);
Also please read for more inormation on issues with NI http://www.csharp411.com/notifyiconshowballoontip-issues/
You may need to post the rest of the code that's in your form's load event, but here's a couple of suggestions:
Make sure the form's Load event is actually hooked up.
Make sure you've assigned an icon for the notify icon.
Also, note that the balloon tip isn't guaranteed to show. See the Remarks section on msdn's NotifyIcon.ShowBalloonTip Method article:
Remarks 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. In addition, if the user does
not appear to be using the computer (no keyboard or mouse events are
occurring) then the system does not count this time towards the
timeout.
Only one balloon tip can display on the taskbar at a time. Attempting
to display a balloon tip when one is currently displayed on the
taskbar causes the timeout value to be ignored. The behavior is
slightly different depending on the operating system and whether the
balloon tip is from another, or the same, application. When the second
balloon tip is from another application, the first balloon tip will
display for the minimum timeout value before the second appears,
regardless of the value of timeout. In most cases, if the balloon tips
are from the same application, the first balloon tip immediately
closes when another call to the ShowBalloonTip method is made. In some
cases the second balloon will open on top of the first balloon.
The title text will display in a bold font near the top of the
balloon.
Here is some sample code for what #MetroSmurf has already mentioned. Note that this.InitializeComponent(); must be called before the NotifyIcon is shown (usually in the form constructor).
public Form1()
{
this.InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
notifyIcon1.Icon = new Icon(#"C:\SomePath\MyIcon.ico");
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(5000, "Welcome", "Hello " + User, ToolTipIcon.Info);
}
Also ensure that windows is configured to allow notifications. In Windows 7 right-click taskbar, click Properties, Customize... in the notification area, tick the Always show all icons and notifications on the taskbar option, click OK.