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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With