I'm trying to implement UI automation in a WPF application but whenever a modal dialog appears the UI automation will hang until the dialog is manually closed.
So far I've tried using a second thread to close the dialog box, setting the application to use MTA threads, using RaiseEvent to raise the Button.ClickEvent on the button to close the dialog, and using sendinput to send a keypress to the dialog.
None of these methods are working and I haven't found any other workarounds to try.
Does anyone know of any possible solutions?
Give ChildWindow a shot:
http://wpftoolkit.codeplex.com/wikipage?title=ChildWindow&referringTitle=Home
Hold the UI is definition and purpose of a modal dialog. If you don't want to hold the UI then you want a modeLESS dialog. The UI is not hanging. The modal dialog is doing exactly what it is supposed to do.
Related
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).
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.
I am trying to do something with the Modal dialog in Win7. To do that I need to know which control window has got focus right now by using Win32 API. If I could know which control is now got focus then I can send message to this window to do some specific task.
Could any one suggest me how should I know which control has got focus right now using win 32?
If you want to know which window has keyboard focus and you're only interested in windows belonging to your own thread use GetFocus.
Finding out which window in the entire system has focus requires a few steps:
GetForegroundWindow
GetWindowThreadProcessId
GetGUIThreadInfo
I have a WinForms app that is retrieving data from a web service on a worker thread and I need to disable all input to my app until the data is loaded.
Currently, I create a semi-transparent form and place it over my application. When the data call completes I close this overlay form. This works fine accept that it causes considerable performance problems for users running the application over terminal services. I tried making the overlay entirely transparent but that still triggers two redraws of the entire window so this did not help at all.
I know that a common recommendation for handling this is to disable all the controls, but that would also redraw much of the screen so I'm looking for another way to block all user input. Any assistance would be greatly appreciated!
UPDATE: I should have mentioned that we have considered the modal dialog. Currently we show the overlay, start the data access thread then construct the form. If there is no better way to block input (App.BlockInput() might be nice) then we could use the modal dialog idea, but we would need to wait until the form construction had completed and there isn't currently a nice, central location to do this.
You could display a small modal (modalForm.ShowDialog(yourForm)) form with progress bar rolling on top of your app. This won't cause big areas to be redrawed.
If your app really is blocked while the operation is running, I'd do what Microsoft frequently does: open a modal dialog box with some kind of throbber animation or ProgressBar, and a Cancel button. Redraw is limited because you're only drawing the size of the new dialog, and input to the rest of your application is blocked because the dialog is modal. Also, users are much more willing to wait when you have some kind of status updates and or animation, because it looks like the computer is "working".
However, if there are operations your user can do while your web service request is running, it's better to leave the controls accessible. At very least, there should always be a way to interrupt/abort the process.
Update: Since you now changed the question: How long is it taking to construct the modal dialog? Why not simply construct the dialog empty, and then populate its controls? If all you have is a small dialog box with a single button and a single ProgressBar, then calling dialog.ShowDialog() should happen faster than your user can interact with your UI. Is that not the case?
One thing you could try for keyboard input is setting the KeyPreview property of the form to True. This will pass all keyboard events to the Form object first instead of to the individual controls. Create an event handler for the KeyPress event of the form and in there you can set the Handled property of the KeyPressEventArgs to True to prevent the key stroke from being passed to any of the controls. If you're currently retrieving data from the web service, set the Handled property True otherwise set it to False and the key stroke will be passed to the controls.
If someone has a good idea on how to handle the mouse input yet you're set.
I'd typically create a LockUI() and UnlockUI() functions in my form that toggle controls and flip a local form field that acts a flag to indicate a long running process. This approach works really well if you use a command pattern.
As previously mentioned, you could toggle keyboard input by using the KeyPreview property of the form (as suggested by TLiebe).
As far as mouse input is concerned, you could disable mouse activity by hooking the WinProc messages and intercepting mouse input messages. This is basically what KeyPreview does.