I have a login prompt as part of a WPF application - when the user enters an incorrect password, a new modal dialog window appears informing them that their password is incorrect.
This modal dialog is launched via ShowDialog(), and behaves as expected - the dialog launches successfully, appears in front of the login prompt that spawned it (I've verified in the debugger that Owner is being set correctly to the login prompt), and the user can't click back to the login dialog until the warning message is addressed.
As part of an external requirement, we have an alternate launcher executable that sets the UIaccess attribute in the manifest file to true. I personally dislike this behavior, but due to business requirements, it cannot be removed. Other than the manifest file difference, the regular launcher and this alternate version run the exact same code, the same dlls, etc.
Here's the issue: on this UIaccess version, when the user enters the wrong password, the dialog warning of invalid credentials shows up behind the login dialog box. Then the user is unable to interact with any part of the application, because the code is still waiting for ShowDialog() to resolve, and the login dialog window is disabled until the user closes the warning prompt (hidden behind the login dialog - inaccessible).
While we were able to resolve this issue by adding a check to the constructor of the modal dialog box that looks like this (the login dialog is always set to Topmost=true, this condition ensures that other dialog boxes of the same type aren't necessarily Topmost):
if (owner != null && owner.Topmost)
Topmost = true;
We're still noticing some behavior that is different between the two versions, but only in the way this login dialog and its modal prompt are displayed - now the modal window appears on top as desired, but the user can click the login dialog and it will move up to the top, though it's still disabled.
The root of the question is: why does the UIAccess attribute change the behavior of ShowDialog() in this way? If both the dialog and the modal window are in the same thread, why should their relative positions be changed by setting UIAccess for the whole application?
Its's strange that UI Access affects the behavior of the modal dialog. Anyway I think only someone from Microsoft can give a direct answer on that. A workaround would be to implement your own custom dialog inheriting from Window where you can react on any changes in position or size. In example if the windowState chages to minimizied you could bring it back by changing state to normal and calling window.Activate(). This would immediately bring it back to TOP.
The custom message box control I implemented for our need was unminimizable Fullscreen window (inherited from Window). I made the background transparent and blured (BorderEffect) and in the middle I showed the message content, title, icon and the buttons. So if the user clicks anywhere it is a click on this window so it will not change the state. I only added IsTopMost and on SizeChanged => Maximize. This will always work. And as mentioned at the beginning this is a workaround where you can take control of your messagebox behavior. The real reason for that strange behavior (bug) is know only to microsoft and to be honest I don't think you will get any solution to your problem from them.
You can try add a new textblock in your WPF application to avoid popup dialog using to show error message,if the dialog windows is must need,you can try use a new thread to manager a new windows to show this error,and then, when this windows popup,you can disable the log in windows in your WPF application,and when get a return value from the message windows,recover it.
Related
I was wondering if there is a window property, for a wpf application, that disables any actions outside of the window. For example, when you open a message dialog and click outside of it, the message dialog background flashes. Kind of saying you can't do any actions outside of the message dialog untill you click the 'OK' button. I want that implemented in some windows that I open in a program i'm developing but can't seem to find any info on it. Looking for ways on how i might approach this.
Try ShowDialog() instead of Show()
Opens a window and returns only when the newly opened window is closed.
Window childWindow = new Window();
childWindow.ShowDialog();
Note that it will prevent clicks only on parent window(s). Clicks on other applications or Desktop can't be prevented by the Dialog.
I have a WPF application using the ICDBurn interface to burn some data to a disk.
After calling ICDBurn::Burn a dialog is shown and the user should not be able to continue working with the application until this dialog is handled, which is not the default behaviour.
I tried passing both IntPtr.Zero as well as the applications main window handle as a parent to ICDBurn::Burn, but the result was the same.
So I want this dialog to be modal, but I would settle for setting this dialog to always on top as well.
As a first step, I figured I would need a handle to the dialog's window. I tried EnumChildWindows but did not find the dialog there.
How can I set this dialog to modal?
Edit:
based on the comment from IInspectable, I maybe passed the wrong window handle to Burn. I am using new WindowInteropHelper(Application.Current.MainWindow).Handle and I think I use no other windows in the application.
Ahh, WPF...
To get ICDBurn::Burn to correctly open as a modal dialog, it has to be called on the UI Thread (using Application.Current.MainWindow.Dispatcher).
I have found several similar questions, but nothing that fits perfectly.
I want my main window to show up first, and if the application can't find an application configuration file I want it to pop up a dialog box to get some necessary values from the user.
If I do anything in App.xaml etc - then obviously the main window won't be open, the same goes for if I put it in my main window's OnInitialized. If I put it in OnActivated, it seems to work, but when I close the dialog or somehow click on the main window it pops up another copy of the dialog. I could put a bool in my main window that indicates whether the dialog box is open already, but that just doesn't seem optimal or the best way of doing things.
Any suggestions?
Use Loaded instead.
my application opens n forms and the user can freely switch back and forth among these forms.
When the user decides to confirm the operations performed on one of the forms, I would like to block the other ones until this process (which can potentially open MessageBoxes and/or other forms) comes to an end.
It is not enough to disable the forms, since the user can't do anything on them, but the Activated event is fired, and this is exactly what I want to avoid.
I tried to set ControlStyles.Selectable to false to all these forms, but it doesn't work.
Just in order to make it clearer, the forms cover the whole screen, so the users activate them clicking on the taskbar. This is the situation where opening a modal form and having the confirm code executed there does not prevent the Activated event to be fired.
Try to use Form.ShowDialog() method.
You can use Form.ShowDialog Method method to display a modal dialog box in your application. When this method is called, the code following it is not executed until after the dialog box is closed.
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.