We have a C# application which contains both modal and non-modal windows. It is possible for a user to have several non-modal windows open and open a modal window from one of these.
If the user switches to another application and then switches back to ours by clicking one of the non-modal windows (other than the one which opened the modal window) in the Task Bar, the non-modal window becomes activated but does not accept input because the modal window is open, but is behind other windows.
How can we ensure that no matter which of our windows the user switches back to, the one which is modal is the one which is actually activated? This is the behaviour exhibited by Microsoft Outlook, for example.
Any assistance would be appreciated.
Its certainly possible, but is really annoying to maintain. I regularly work on an application which mixes modal and non-modal windows. This is my strategy (which isn't 100% full-proof)
Set the modal windows TOPMOST when
possible.
When certain actions are
detected (like pressing windows-d button),
you have to manually set the window
back to topmost. I dont know why the windows go to the back, but the behavior is not consistent between windows XP, vista, 2003, etc.
Its really annoying maintaining the code that rearranges the windows. I would urge you to try to not mix modal and non-modal windows.
Edit
I forgot to mention that i use WTL and alot of native win32 functions. I also try to create windows which have parent / child relationship so that keyboard and mouse messages get REFLECTED as much as possible to the child windows.
Related
I am trying to create a parent WPF/surface application which will host multiple WPF/surface applications. I am looking for some pointers of how to implement such functionality. Was reading http://msdn.microsoft.com/en-us/library/ms742522.aspx but it talks about hosting Win32 content in WPF and vice versa.
My idea is to have something similar to MDI forms where you have a main form and you can instantiate multiple child forms.
In my case, these would be different applications which will be launched using a config file and loaded within the main application.
Also, since is there a way to ensure that the main window's process memory is not hogged by the child process initiated.
Edit:
The host application will launch different applications based on what user selects. One can say its like an application launcher which are build on WPF/Surface touch SDK. Now once the application is launched the launcher goes in the background(except showing small button to bring it forward again at some point later) and when the user ends the current application launcher comes back again in foreground. The only interaction i feel which is necessary is knowing the launched application is terminated or invoking applications in a limited screen area. If someone has seen the Microsoft surface application launcher, even when the application is launched there are corner buttons which bring the app launcher to foreground.
I would first look at using Microsoft Prism, specifically the Modularity namespace.
Except for the "different applications" part, it sounds like a classic case for MVVM. Are these "different applications" actually separate applications, or could they simply be separate projects within the same application? That may simplify the choice of presentation.
I suppose you could still have a View called "Host" that presents a different app.
Of course, WPF doesn't have the concept of MDI, but you can open multiple, non-modal windows.
It really depends on what you mean by "hosting". Does the main window need to somehow handle and/or interact with the other applications, or is it just a launching pad for other applications?
I followed this approach to solve this problem. The launcher was not hosting the application within itself but would launch a new application and hide itself.
Steps I followed:
The main launcher application will run in Kiosk mode i.e always on top/no option to close by capturing the close event/No instance shown in taskbar/no title bar/killing the explorer.exe/hiding the taskbar.
The launcher populates a horizontal listbox (data templated for UI) which lets occupied main center area of screen and can be scrolled either ways.
When user selected an item on listbox, click/tap event a separate process is launched with launcher window's visibility set to hidden and a small button(basically a window with just a button inside and size set to height/width of button) created on the either corner of the screen with always on top option.
The functionality of button is to minimize the current working application and set visibility of launcher back to visible and setting the focus to this window.
Since the process is launched by launcher, i trap the close event for the launched window to know user ended the application and then again pop up the launcher back.
When I set focus on a text box, on a forms load event in Windows Mobile 5.0, the Windows tool bar appears even though my form is maximized.
When I do not set the focus on the text box the form opens maximized. I do not want the windows tool bar appearing.
How do I prevent this from happening?
TThe start bar in WinMo is actually not part of your app - it is a separate process managed by the Shell and it really wants to always be on top. Trying to get your app above it goes against the design goals of WinMo (though it's a common thing to want to do).
I'd recommend doing some searching and reading on "kiosk mode" to garner what knowledge you can from others who have been down this road, but what you're seeing is that the StartBar is getting set topmost.
Raffaelle Limosani has a pretty decent blog entry that covers kiosk mode, so it's a good place to start (take a look at the other blogs he links to as well).
The toolbar at the top is actually a separate window, and it has a habit of appearing when not wanted over top of a full-screen ("kiosk" mode) app. For example, if you ShowDialog a second full-screen window from the first, the Start window flickers up for a split second before going away.
The only way I ever found of dealing with it was to hack into the API and actually make the Start window hidden while my application was open. This is a big potential problem, because if your app crashes without making the Start window visible again, it will stay invisible until you reset the device (or run you app again successfully).
I'd advice against doing this unless you absolutely have to. As ctacke points out, this would be an example of an app not playing nicely with Windows Mobile.
Suppose, I have the following task.
There is a main application form with numerous buttons; when you click on each of these buttons, you get one more form. The second click on the button should close the opened form.
These forms should not be shown in taskbar, because they are auxiliary. They should not be dialog, because that will block the main application form and prevent user from performing some other operations with the main window or with other forms like the one that is opened. They should be shown above the main form, but not above other windows (so TopMost doesn't suite). When such forms are closed, the main form should be notified, and when the main form is minimized, they should be minimized as well.
How would you solve this problem?
The current solution is based on using hooks. It's not very easy to understand and very difficult to maintain (mainly because I am not experienced in win32). It works fine for about 90% of situations, but in 10% it doesn't.
Maybe, the requirements to forms behavior are to strict?
I would recomment using some window-manager, so each button will tell the window-manager to toggle visibility of form X, if X is not there it will be shown, if it is, it will be closed.
You should be able to configure the windows such that they will not show up in the taskbar.
For the visibility, I am not sure what you mean. When you open a form via a button, it will usually go to front, which should be ok. If you switch the window then, what do you expect? Should the main window always stay in the background or is it allowed to come to the front when focused?
Whenever I have seen applications change such standard behaviors, they failed in some way. Either wrong windows showed up or some were not accessible anymore or the user was just confused because these windows didn't act like all other windows.
It's not a problem. Use the Show(owner) overload to display the form.
An owned form is always on top of its owner. It minimizes automatically when you minimize the main window. No need for ShowInTaskbar. Another window model supported by winforms is MDI, check out the MdiParent property. The child windows are confined inside the bounds of the main window. Also consider using UserControls instead of a form, you can swap them in and out as needed. Or a tabbed interface, using TabControl. Weifenluo's DockPanel suite is a very popular implementation of the Visual Studio style windowing model, supporting windows that can be docked and floating within the main window. Plenty of choices here :)
Here's how most of your requirements can be accomplished:
Set the Owner of each child Form to be the Main Form.
MSDN Quote:
When a form is owned by another form,
it is closed or hidden with the owner
form. For example, consider a form
named Form2 that is owned by a form
named Form1. If Form1 is closed or
minimized, Form2 is also closed or
hidden. Owned forms are also never
displayed behind their owner form. You
can use owned forms for windows such
as find and replace windows, which
should not disappear when the owner
form is selected. To determine the
forms that are owned by a parent form,
use the OwnedForms property.
For stoping a form from appearing in task bar you need to set the ShowInTaskBar property
I am using C# and WinForms to create UI of my application.
I have main window and dialog, which is shown modal to the main window. Dialog window is not shown in task bar. I go to another application and return back by clicking at the main window task bat icon. I can see locked main window but cannot see dialog unless I select it in Alt-Tab. This is confusing for an application user.
How can I ensure showing modal window in this situation? I can see similar but unfortunately unsolved question ALT+TAB in Vista activates main window instead of previously active child window which regards to Vista (and I have Windows 7).
This is probably because you don't use the ShowDialog(owner) overload. You should fret a little bit about the exact reason that ShowDialog() cannot find an owner by itself and picked the desktop window instead. It isn't healthy. I cannot guess why from your post. See what explicitly setting the owner buys you.
Oh, this will happen when the dialog runs on its own thread. In which case ShowDialog(owner) is going to bomb.
It sounds like your dialog is not properly owned by the main window. Make sure you have assigned the main window to the dialog object's Owner property before showing the modal dialog.
I would like to display a status window in my C# Windows Forms application that informs the user when the application is waiting to acquire a lock. This is an application-defined thing, however, the window should be visible and always remain on top of all other windows of my application, even when the user clicks on another window (like for example the larger main window behind it).
It must not be modal (so ShowDialog() cannot be used) because the app needs to keep trying in the background and close the window automatically if the lock could eventually be acquired, and it really should not be top-most for the entire window station (i.e. all applications running in that terminal session).
I know the Form.TopMost property, but it can only bring and keep a single window above all others, even those from other applications. This is clearly not what I'm looking for.
I know that this is possible, I've seen it many times before in other applications. I just don't know how it can be done.
If you pass your main form into the Show method of the status form, it will stay on top of the main form, but not on top of other applications. So, in the main form you can have code like so:
StatusForm statusForm = new StatusForm();
statusForm.Show(this);
However, this will only point out one single window of your application as the owner.
You have to set the Owner property of the child form to the parent form, and use Show to show the child form.