How can I make some functionality of my WinForm application accessible even if running a Modal Dialog? - winforms

I've got a "Main Window" containing quite a few things, including, in the status bar (at the very bottom of the window), a "Support" button, which the user can use at any time to open a window containing our support phone number, along with a little chat functionality if the user prefers to chat with us.
The problem is that if the program is displaying a modal dialog, the "support" button is not clickable anymore.
Stopping using modal dialogs is not an option ; I use them because I sometimes want to force the user into performing a specific task before I can do something else in the software.
What's the best way to let the user contact the support without having to close the current modal dialog?

Modal dialogs should behave as modal dialogs, the user won't expect to be able to click a button in the main window even if it were possible.
Your best bet is to put a support button on the dialog too.

Using a shortcut key instead of a button may be an option. The functionality could be factorized into a base form class like this :
public class BaseForm : Form
{
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == Keys.F1)
{
SupportForm f = new SupportForm ();
f.Show();
}
return base.ProcessDialogKey(keyData);
}
}

Not using modal dialogs is an option. You can disable other parts of your interface during the required interaction to get whatever it is that you need out of the user.
The solution is to avoid situations where the user 'must' do something. Modal dialogs often get in the way if, for example, the user wants to quit the application right at that moment, or see something in a backgrounded window, or refer to another part of your application. Instead of using them, design your interaction so that if there is a required action/piece of information, it's folded into the application logic.
Think about website design -- modal dialogs are very rarely found on the web, and for good reason -- they disrupt the user's workflow unnecessarily. And yet plenty of sites have 'required' information.
Don't use modal dialogs; they are a shortcut to avoid a better design.

Related

Create a "COMMON" confimation dialogue - possible approaches and best practices

I have an application based on the presentation of one or more tabs. Each tab type identifies a specific activity (e.g. create an object of a specific type, like user, user profile, etc.).
Any tab type can concurrently appear one or more times at any given moment (e.g. two or more Create User tabs can be open at the same time).
For those tabs that accept inputs like the examples above, I would like to build a common "Close Confirmation Dialogue" mechanism that would be popped every time the user attempts to close a tab before saving the data while the data of the tab had been changed.
I did some tests that work OK under sterilized conditions, but when testing basic combinations the behavior begins to become strange.
The dialogue would need to return an indication of what the user selected (e.g. "Proceed with Tab Close" or "Cancel Tab Close request").
I was thinking about creating a service that would handle this, but I'm not sure if the use of a callback function (passed to the service from the tab's controller) would be suitable to return to the tab controller the selection of the user.
If possible, I am keen to find some examples on how this should be done.

Codename One nested Sidemenu

I am trying to create a nested side menu for a CN1 application, similar to the one in the screenshot.
For the nested sidemenu to work, I image it has to stay open when the user presses a command of a dropdown list , so that he/ she can choose an option.
But the CN1 sidemenu appears to close every time and I couldn't find a workaround.
One approach I was trying was to add an action event to the "hamburger menu ", but this doesn't seem to work.
Button sideBtn = (Button)((BorderLayout)bar.getLayout()).getEast();
sideBtn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent evt) {
Toolbar.setPermanentSideMenu(true);
};
Neither does adding Toolbar.setPermanentSideMenu(true) to any other button's action event.
Anther approach I have in mind is to add hidden buttons to the sidemenu and repaint the toolbar when the button is clicked, but this still does not keep the sidemenu open and seems to be not very direct.
Is there anything more straightforward? What would be the best approach?
Thanks in advance for any kind response.
The setPermanentSideMenu method is designed for tablets and not for what you are trying to do. Toggling it after the init(Object) method was invoked doesn't make sense and might break your app.
You didn't list how you added the button to the side menu but adding it using addComponentToSideMenu(Component) should work (notice I didn't use the version that accepts a Command).

When Modal Dialog is shown in WPF and a user clicks on the parent window, make the modal dialog flash, blink or shake

New Thought, Maybe I am looking at this totally incorrectly. So Here is exactly what I am trying to do in case there is another option I am not aware of.
I have a WPF app, the main window shows a smaller dialog window using ShowDialog(), when a user clicks on the parent window that showed the dialog, I need to make the dialog window, flash, shake or blink.
AresAvatar posted a link that looks like it might be able to use, but is there another option I am not aware of?
My original Question.
Mouse click event when Modal window's parent is clicked in WPF app?
I have a wpf app that shows a modal window using ShowDialog().
I would like to fire an event when the user tries to click the parent window that is now disabled.
Is it possible on the parent to receive a click event when it has shown a modal window?
When I attempted this using an interaction trigger, the events never fired on parent window.
Otherwise, what suggestions / options are there.
Thanks
No WPF events are sent under these conditions. The only Windows message I can see that gets sent is WM_WINDOWPOSCHANGING. You could check for that message, and check if the window was disabled when it occurred. Here's a good article on checking WM_WINDOWPOSCHANGING.
Edit: that link seems to be dead. Here's an example on StackOverflow of checking window messages.
I know this is an old question but I'll post my solution in case any one needs it.
Set the dialog.owner prior to calling ShowDialog().
var dialog = new DialogWindow();
dialog.owner = MainWindow;
dialog.ShowDialog();
The result is that clicking on the main window, brings the dialog window to the front and makes the dialog window flash.

WP7 - Determine where the app will go when the "back" button is pressed

I'm working on a WP7 appliation with Silverlight. When a user clicks the back button, I want to determine where they will go to. Is there a way to determine where a user will go without managing my own nav stack?
thanks!
To respond to the question that has actually been asked "Is there a way to determine where a user will go without managing my own nav stack?"
You could use the OnNavigatingFrom override the eventargs of which carries the Uri of the page being navigated to. I suspect this is only useful when the navigation is back to page within your app.
You cannot override what the back button does - the rule Derek mentioned is enforced by the system and the previous page/app will always be called.
You can, however, add an action to be executed on back key press:
this.BackKeyPress += new EventHandler<System.ComponentModel.CancelEventArgs>(MainPage_BackKeyPress);
Then just use the handler:
void MainPage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
{
// Your activity goes here
}
The application will go back to the previous page when the user presses the Back button. If the user is at the last page in the application, then the application will exit and the user will be navigated to the previous application. To perform anything else would be inconsistent, confusing to the user, and almost certainly would fail certification.
In general you'll want to build your app composed of pages (similar to a website). For example a HyperlinkButton might be used like this:
<HyperlinkButton NavigateUri="/Page2.xaml" Content="Click here to enter page 2"/>
After clicking that then pressing the back button will automatically return to the previous page. There's no extra programming involved to make this happen... it just works.
But there are some circumstances where you'll want to override the back button. The one I ran into was the dialog box. If your app creates a dialog box, then the back button should close it instead of returning to the previous page. I wrote a brief article about how to accomplish this.
And here's a complete list of rules from Microsoft's certification requirements concerning the back button:
To maintain a consistent user
experience, the Back button must only
be used for backwards navigation in
the application.
a. Pressing the Back button from the
first screen of an application must
exit the application.
b. Pressing the Back button must
return the application to the previous
page.
c. If the current page displays a
context menu or a dialog, the pressing
of the Back button must close the menu
or dialog and cancel the backward
navigation to the previous page.
d. For games, when the Back button is
pressed during gameplay, the game can
choose to present a pause context menu
or dialog or navigate the user to the
prior menu screen. Pressing the Back
button again while in a paused context
menu or dialog closes the menu or
dialog.
As I found out, if you don't follow those rules they won't approve your app.

How can I make a 'Partially' modal dialog?

Is there a way to start off showing a dialog modally, but then instead of hiding it, to keep it visible while changing it to a non-modal dialog?
I want to show a dialog, blocking the method that shows the dialog. Then when the user clicks the 'Finish' button on the dialog I want:
The dialog to remain visible.
Control to return to the method that showed the dialog.
I've achieved this result by running the dialog on a separate STA thread, and using an event to block the main UI thread until 'Finish' is pressed, but there's a catch to this method: you can click on the close button of the 'main' window while the dialog is visible, and the main window closes when the dialog is hidden.
Update
Thanks for the responses so far. Sorry - it looks like I got the balance wrong between too much background and not enough.
The form is effectively a modal 'wizard' dialog - it appears, sits in front of the main app modally, and then is hidden. So as far as the user's concerned there's no non-standard weirdness going on. The only difference is that the dialog is driven from a series of callbacks from the UI thread, so I don't think making it truly modal (via a call to ShowDialog) for its lifetime would work. The first callback must show the dialog, and then block while the user sets their preferences via the dialog UI. After that, the dialog stays visible and displays a progress bar page while various other callbacks are made from the UI thread. Eventually the form is hidden. The user isn't interacting with the main window while the form is up. As far as they're concerned, it should appear to be 100% modal wrt the main UI thread.
(The form is a dialog for a Visual Studio wizard - these are driven from a series of callbacks on the UI thread). An alternative would be to show the dialog, hide it, immediately show a topmost 'progress' form instead and then hide that, but I think showing a single dialog is more seamless an experience for the user.
Again - sorry for the confusion!
Perhaps you want to rethink your interaction model? How are you going to explain this to your users? They have an internalized model of how computer programs work, and you better have a very good reason to break that. They know about modal dialogs, they know about non-modal dialogs, they know about inspectors. Choose one, and apply it.
Modal dialogs are made for short-time interaction. They should not block exiting the application. The user is in control of the interaction, the program only provides the minimum of restrictions needed.
[after the explanation, replaced]
What's wrong with showing the progress bar in the modal dialog? Start processing once ok
is clicked, disabling all buttons, only keeping the cancel button active? If it takes a long time, the user might want to abort the action. Only close the dialog when you're finished processing.
You could use a modeless dialog then have your main UI check if the user has clicked the Finished button. If the modeless dialog is open but Finished hasn't been clicked then don't respond to any users actions in the main form...
This is just a terrible idea - it's completely non-standard behavior and you're going to jump through all kinds of hoops to get something working that is just going to horribly confuse your users.
Like most of the other answers here stated, you're implement non-standard UI elements that will be confusing to most users.
If the dialog remains visible just to provide read-only access to the data, then why not have dialog window close normally and open a side-bar window in your application with the data from the dialog window?
If the dialog remains visible to allow the users to continue making updates in it, then perhaps, it shouldn't be modal to begin with.
Point is, there's a couple different ways you can accomplish your task without breaking standard UI metaphors.
I'd make it a flyout from the side or bottom of your app that shoves other things out of the way. If it's on top of other stuff that the user might need to see or interact with then it's just gonna annoy them.
I found that showing an an invisible modal dialog on the main UI thread during the blocking stage of the interaction works great.
Hidden modal dialog settings (so it's not visible): ShowInTaskBar=false, FormBorderStyle=None, size={0,0}, Opacity=0%, StartupPosition=CenterParent.
The hidden dialog is shown on the UI thread using ShowDialog. The visible dialog is shown on a separate STA thread. The thread is kicked off before calling hiddenDialog.ShowDialog on the main UI thread.
The visible dialog hides hiddenDialog when it wants the initial blocking state to complete. This stops the main UI thread from blocking.
The important bits of code:
void LaunchWizardForm(s)
{
// Show the wizard on its own thread.
ThreadStart t = () =>
{
_wizard = new WizardForm(s);
Application.Run(new ApplicationContext(_wizard));
};
var thread = new Thread(t);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
// Block this (main UI) thread
_hiddenForm.ShowDialog();
}
void EndModalEpisode()
{
_hiddenForm.Invoke((Action) (() => _hiddenForm.Hide()));
}

Resources