Alternative way to notify the user of an error - c#

I have a winform software that communicates with hardware through a protocol.
Sometimes error in communication happens and i would like to notify the user. Errors could be for example: timeouts, crc errors, physical disconnection etc...
I have a communication window in which i show these errors, but by default this is hidden. The user can open it though the menubar.
Popups are annoying to the user (and to myself) so i would like a un-invasive way to notify the user that an error has occurred. Perhaps a info bubble like when XP tells you updates are ready for your computer? I know that NotifyIcon can help put things in the system tray, which i do not wish to have. I'd rather keep it within my MDI.
I'm open to other creative ideas as well.

There are several alternatives that can be employed when an error occurs, each with their own advantages and disadvantages:
MessageBox popups
Display a message box popup to the user.
Advantage: since it is modal, the user has to acknowledge the error to continue.
Disadvantage: since it is modal, it interrupts the user from whatever they were doing. Multiple errors are also inconvenient, requiring multiple confirmations.
Show the communication window
If your existing communication window is hidden, display it to make the logged error visible.
Advantage: uses the existing familiar communication mechanism.
Disadvantage: if the user does not really care about the errors, it could be annoying that the communication window continually reappears.
Status bar messages
Show messages in the status bar of the application.
Advantage: will always be visible on screen, but is "out of the way" of the main window.
Disadvantage: hard to display multiple messages and may be missed by the user.
Balloon notifications
Show an Outlook/MSN Messenger style notification message near to the notification icons.
Advantage: is obvious enough for a user to notice, but does not necessarily require a notification icon. Could also collate multiple messages into a single popup.
Disadvantage: could be annoying to the user.
Notification icons
Show a notification icon (perhaps with a balloon notification).
Advantage: is obvious to the user, but still unobtrusive.
Disadvantage: is yet another notification icon to clutter up the user's desktop.
Personally, I would choose option 2 as it requires the least amount of effort to achieve. If it is unacceptable once people start to encounter it, review the other alternatives.
For examples of balloon notifications that do not require a notification icon, see this for Windows Forms and this for WPF.

One (relatively) common paradigm is to place a message on the status bar ("[x] New Messages"), and make the appearance of the message window a user action.

If your MDI window is open/visible, then you could have a comms status icon on it - this would be green when everything is fine, orange for warnings (like corrupt packets have been detected, but comms is still working and the system has recovered), and red for errors (like no decodable comms received for 5 seconds). This allows it to be fairly subtle when things are wokrking, but quite noticeably "different" is a problem occurs.
For a serious error (e.g. disconnection) you may want to get more "invasive" because there comes a point where not bringing the problem to the user's attention is worse than bothering them with the error report.
If your window is not guaranteed to be visible then (despite your dislike of the idea) a system-tray icon (to show this status) is a standard and rather clean solution - it can be permanently visible or simply appear when it is relevant, it's about as non-invasive as you can get while still bringing information to the user's attention, and easy for the user to check periodically to reassure themselves that they have a "green light".
An alternative to visual indicators is to use audio alarms.
(For example, we use a monitor on our build server. It simply has a green icon when the builds are good, and a red icon if a build has failed. This is perfect, as it doens't bother me at all but I can check the build status in an instant.
Alternative example: I have an email app that shows an "envelope" icon in the system tray when I have new email, and nothing if I don't. In practice with this system I notice pretty soon (within a minute or two) when mail has arrived, but I am not bothered by constant popups or message boxes.
I think these are both examples that show how much better a system tray icon is than a popup or balloon window. Popups are irritating and with most of them if you aren't watching when they appear, you miss the information. I'm forever spotting popups just as they disappear and then having to open the app to find out if they were telling me anything useful. Which usually they weren't. The same goes for audio notifications: I keep hearing random noises from my IM application and wonder what the heck they mean).

Depends on your scenarios: If the event requires user interaction to resolve, then a modal dialog may well be the best approach because you can't continue until the user, for example, inserts the device into a USB port (or whatever).
For other unusual notifications that the user may need to be aware of but may not disrupt the workflow, I suggest using an in-app popup-toast or updating the status window.
If the user doesn't need to change/interrupt what they're doing, then don't warn/notify them: your device and app should "just work" - the user should only be interrupted if there's something that truly requires their attention or that will cause them disruption "soon".

this put a small red circle at rightside of control. its kinda datagridview cell erroText style
var errorProvider1 == new ErrorProvider();
protected void textBox1_Validating (object sender, System.ComponentModel.CancelEventArgs e)
{
try
{
int x = Int32.Parse(textBox1.Text);
// Clear the error.
errorProvider1.SetError(textBox1, "");
}
catch (Exception ex)
{
errorProvider1.SetError(textBox1, "Not an integer value.");
// additionally, if you wantto prevent user leaving textbox
// until he satisfies condition. uncomment below.
// e.handled = true;
}
}
From: Microsoft

Related

Override handling of taskbar command "Close all Windows"

I have a WPF-application with multiple unrelated Windows, i.e. there is always one MainWindow and optionally many others with no owner.
If these windows get grouped in the taskbar, windows will provide the action "Close all Windows" in the taskbar context menu.
If it is clicked, each Window of my application gets an individual close-command in an order I cannot control.
Problem:
Some of my windows may ask before closing, if it's okay to cancel pending changes. This is annoying and confusing if there are many of those.
What I want is: If the MainWindow is asked for closing, I want to prompt once, if that's ok. If yes, all windows should close silently, otherwise stay open.
But my MainWindow is not the first one, to process the closing procedure.
I have already found out, that I probably need to check the Windows Message Loop of my MainWindow for some WM_SYSCOMMAND with wparam SC_CLOSE.
(see How can I distinguish between "Close All Windows" and "Close" individual windows in MFC with Windows 7?)
But how can I evaluate this, before I execute the closing-routine for any other window?
ComponentDispatcher.ThreadPreprocessMessage in my mainwindow comes too late, it fires after some other window has started the closing procedure.
This question is somehow related to this one:
Odd form closing behavior when using taskbar's Close All Windows
Personally, I would just leave things as they are. I can see how having several prompts to save/cancel changes could be annoying, but it doesn't seem confusing to me. And while annoying, it seems like a minor annoyance, and frankly one that might teach the user to not use the "Close all windows" option when they have left a bunch of these windows open. That said…
As the question you've found points out, there is no built-in way to distinguish the "Close all windows" from a regular "Close window" command. The system is simply sending the messages to the windows in sequence.
In MFC (i.e. the context of the other question), you can call AfxGetCurrentMessage() to retrieve information about what actually instigated the SC_CLOSE message. If it was user input that was translated to a close command, there will be some type of user input (keyboard, mouse, etc.) as the current message. Otherwise, you'll just see the WM_SYSCOMMAND itself.
But you can't apply the same approach in WPF, because WPF doesn't provide a GetCurrentMessage() method or its equivalent (as far as I know). The only access to window messages you get is to override the Control.WndProc() method, and by the time you get the close command, the most recent window message there will always be the SC_CLOSE.
It seems to me that the best you can do is use the WndProc() override to track incoming messages, so that you can reset a flag when non-close-command messages come in.
Then, when you get the close command and display the user prompt, you can check that flag. If it's set true, then you can ignore the prompt and just use whatever the user most recently selected. Since you're clearing the flag any time non-close-command messages come in, the first close command received will always display the prompt.
Another alternative would be pre-emptively close all the remaining windows. Here you'd still have the prompt have some kind of "apply to all other windows" option for the user, but instead of setting of just relying on the flag, you could actually close all the other windows explicitly.
Neither of these are ideal, from a user-interface perspective. The main problem is when the user tries to close just a single window. In the first approach, the user will see the "apply to all other windows" option in the prompt even though there won't be any other windows to close. The second approach is a bit more self-consistent, but adds a feature you may or may not want: the user can close all windows in the program any time they are closing just one window.
Neither of these behaviors are exactly standard Windows user interface behaviors. I.e. in trying to save the user some annoyance (and confusion, though like I said, I don't see that part being the case), you introduce what itself could be potentially confusing to the user.
Given that it involves additional work coding, and may simply exchange one annoying/confusing result for another, the best solution may be simply to not try to address the issue at all.

stop auto hiding tray notification icon

Whenever my windows forms application runs for the first time, the tray icon stays visible for about less than a minute, and then it autohides, what can i do to make it stick and not auto hide ?
I tried searching and can't find any useful information.
It appears that this is the default behavior for windows 7 and above, I wonder if there is a way to override that behavior from inside my application ?
There is no supported programmatic way to override the system's default show/hide notification icon behavior. MSDN:
When an icon is added to the notification area on Windows 7, it is added to the overflow section of the notification area by default. This area contains notification area icons that are active, but not visible in the notification area. Only the user can promote an icon from the overflow to the notification area, although in certain circumstances the system can temporarily promote an icon into the notification area as a short preview (under one minute).
Emphasis mine.
As you've no doubt read the discussion in the comments, there is indeed no supported way of doing this. That said, if you're determined and you have the time to do a little digging, I'd recommend using a few tools to bypass the documentation and looking at what's actually happening under the hood with the notification setting. There may be appropriate documentation on this but I've not found it.
The brute force approach would be to use SysInternal's RegMon tool to view all registry access . If you tie it to the "Explorer.exe" process, you will see all relevant information on what the desktop and start bar are doing, including any file access. Make no mistake - this is a brute force approach and will require a lot of effort and digging. Once tied to the explorer.exe process you can make changes to the notificaiton settings. Viewing and investigating the changes made by the process will give you an idea of where the relevant settings are stored and how. The downside is that there's going to be a lot of data to trawl through and investigate to find out what's going on but it can be done. This is not an ideal solution but if no other is forthcoming you're left with the rough and ready approach I'm afraid. It comes down to how much effort you want to put into a solution to this.

How do I make a window compulsory for the user to enter some information?

At my workplace, I need to create a questionnaire that is compulsory for the user to fill out. The aim is to make it as non-intrusive to the user as possible and link it to their Windows account. The results will then be stored in a database where reports can be generated off of the responses.
The suggestion was to load the questionnaire at login time, i.e. when the user logs onto the computer. I would have to make the window exclusive so that no other windows could be interacted with.
My question how would I go about doing this? Could this be done with WPF or would I need XNA or something similar?
Also, are there any other suggestions on how I could meet all the criteria with a different implementation?
Is there a way to run/activate an application at screen unlock?
You can create an app with WinForms or WPF. I don't know about XNA. :) And you can load it on startup; by using Registry. You may need to manually disable ALT + Tab, using API, to disable the interaction between other windows.
First off, it appears you may have conflicting requirements - "non-intrusive" and "compulsory" - to a user any interruption can be considered a violation of their sacred time :)
I would use a Maximized WPF Window that allows transparency, has no window style, fairly transparent to look like the background is disabled. The "form" area would be centered on the screen. The form, once filled out, would close and set a per-user state in a settings.config file to ensure the next time the user logs in it doesn't show up again.
Anuraj has it right to attempt to disable as much interaction as possible via the supression of special keystrokes.
I would suppress the keystrokes by marking the KeyEventArgs as handled upon the raising of the PreviewKeyDown event.
I've never done this on multiple monitors, though, don't know how that would look.
Compulsory is done by, as you say linking it to their domain accounts, and then giving anyone a written warning who has not completed the questionnaire in some time frame.
If you are not willing to back your "compulsory" requirements with actual discipline procedures then implementing technical obstructions is a waste of time. With discipline procedures in place, technical obstructions are unnecessary to achieve compliance.
The actual implementation would probably be best done on the corporate intranet server as a web-form.
This of course requires that the company is mature enough to be using a central login server of some kind (domain controller if windows) and has a corporate intranet.
Now is a good time to start perhaps.

How can I alert the user after a long running process has finished?

I'm looking for some ideas for alerting a user when a long running process has completed from a winforms application. The process could take a couple minutes or a couple hours depending on their inputs, and more than likely they'll just minimize the application and work on something else in the meantime. I know I can do something like playing a windows sound like this:
System.Media.SystemSounds.Exclamation.Play();
But most users here in the office don't have speakers so I don't think it would be very effective.
What are some other techniques I could do to tell the user, "Wake up!!! Your data is ready for you, finally!!!!"
Thanks!
Some ideas:
Animated or changed system tray icon
"Toaster" popup from the system tray (like Outlook, messenger, or some AV apps use)
Blinking alert in taskbar
Send an e-mail
Play a sound/audio alert
Message box
Have an indicator in the status bar at the bottom of your app
Of these, I like the system tray icon + toaster pop up the best. Blinking alert in the taskbar is too demanding, e-mail has too much latency and requires too much configuration, audio alerts have the issues you mentioned in the question, message box blocks execution of it's thread, and a status bar indicator is too subtle.
This sounds like an ideal use case for a notification in the taskbar's Notification Area.
This has the advantage of alerting the user immediately without relying on things like sound that may or may not be available on the user's computer and without the invasiveness of a message box.
...except you might say "Process completed" instead :-)
Open a Message Box.. if the app is minimized it will flash on the start bar.
How about blinking the form in the taskbar similar to how most IM programs blink when a new message is received. You'll need to P/Invoke to get that functionality, but it's actually very easy:
http://pietschsoft.com/post/2009/01/26/CSharp-Flash-Window-in-Taskbar-via-Win32-FlashWindowEx.aspx
You don't need speakers to do the console beep...
Console.Beep();
You can allow the user to customise how they want to be notified if you've got the dev. time.

Dialog MessageBox sometimes hidden behind the main form

Some of our non-technical users are having problems where a dialog MessageBox in our application can sometimes be displayed behind the main form and the application does not accept any input until the messagebox (which they can't see) is dismissed.
The application is written in C# and the message boxes are standard eg the code can be as simple as MessageBox.Show(message, caption) and the messageboxes can be created by the main UI thread (ie not some background thread). The Application does not have to be run full-screen, but 90% of our users do run it full-screen.
Most of the time ((maybe > 99%) the messageboxes display correctly and I have never managed to see how it goes wrong, but I have seen a machine when it has gone wrong.
One thing I did notice is that if you have an application which displays a dialog box, then when you look at your taskmanager, you normal only see one entry in the application list. Whenever the messagebox is hidden, you will see two entries, one for the main application and another entry for this message box.
It is easy enough to fix the problem once you know what has happened, but some of our non-technical users are confused by it and end up switching off their computers. (And the ones who are using Remote Desktop are even more confused when that doesn't solve the problem).
I do not think it is related to the operating system as I have seen it happen in Vista and have been told it also happens in a terminal session on a Windows 2003 server.
Does anything know why this is happening and more importantly if anything can be done to avoid it?
Some overloads of the MessageBox.Show() method take an IWin32Window parameter as the first argument. If you pass in your Form as that first argument it should prevent this from happening.
Is it always the same message box (for the same message?) coming the same form?
Ideally, you should try to find some way to reproduce the problem at will, or at least automatically. This will make your debugging easier and you can then be sure that your future change will have fixed the bug, rather than have to wait for a few weeks for the feedback from your users.
If it is always the same message and in the same window, resulting from the same action, and if the MessageBox call is reasonably easy to trigger from an user point-of-view and if your UI is relatively standard, you could automate the UI with an AutoIT script and have it run in a loop until the problem happens.
And/or, you could create a "debug"-build of your applications that you could give it to some users (preferably the ones that seem to run into the problem the most often) that would write the contents of a StackFrame object to a log file or something similar everytime before calling a MessageBox (you could create a wrapper around the MessageBox to make this easier).
Then, when one of your users gets the problem, you can look at the log file and see where it came from (source code file, line, calls stack etc). You could also compare this to the logs from other users and see if, everytime, the MessageBox comes from the same location or if it varies.
This would show you where the problematic MessageBox is called from and where.
There may be easier solutions (especially if your application has a lot of assemblies) involving some .Net debugger that you would attach to your application when the problem occurs in order to see the call stack, etc, but I only did this with native applications (using OllyDbg) so far and not .Net. Others may be able to expand further on this idea...
Confirm the problem. What we do to fix it is following:
Run new Task and display the message box
In the main UI thread while task is still running - wait in the loop that does DoEvents. Something like this
UPDATED 2015-12-17.
Reproduced problem yestarday. To repo in my case - minimize the app, "wait" popup occures (in our case it happens after some idle time), then in the task bar click on the main app icon. This "hides" the popup so it is not possible to bring it on the screen. The code below was tested and solves the problem. But I still do not understand what/why it happens.
private static DialogResult ShowMessageBox(
string message,
string caption,
MessageBoxButtons buttons,
MessageBoxIcon icon)
{
var showMessageBoxTask = new Task<DialogResult>(() =>
{
var form = new Form() {TopMost = true};
var result = MessageBox.Show(
form,
PrepareMessage(message),
caption,
buttons,
icon);
form.Dispose();
return result;
});
showMessageBoxTask.Start();
while (!showMessageBoxTask.IsCompleted && !showMessageBoxTask.IsFaulted)
{
Application.DoEvents();
}
return showMessageBoxTask.Result;
}
You say "the messageboxes can be created by the main UI thread", which I assume means they aren't always created by the main UI thread. Your problem sounds like MessageBox.Show is occasionally called from another thread.
In the parent form, add this before MessageBox.Show():
this.TopMost = false;

Categories

Resources