I have a WPF window in a VSIX application that I show as follows:
var myWindow = new MyWindow(this.CurrentWorkspace)
{
Owner = Application.Current.MainWindow
};
myWindow .ShowDialog();
However, after I've closed this window, I then get the following error message:
Microsoft Visual Studio has detected that an operation is blocking
user input. This can be caused by an active modal dialog or a task
that needs to block user interaction.
What am I missing?
Note, this may not need to be a dialog window, but I had a problem when it wasn't.
I've encountered this a number of times, and the easiest way to avoid this problem is to derive your dialog from Microsoft.VisualStudio.PlatformUI.DialogWindow, to ensure it's properly parented, and the IDE's modal state set accordingly.
Basically, the issue here is that the IDE doesn't really know about your dialog, it could be implemented via Win32/WinForms or WPF, and invoking IVSUIShell.EnableModeless, works for the former, I've never been able to make it work with the latter. So I just derive from the Microsoft.VisualStudio.PlatformUI.DialogWindow and let it handle the details.
Sincerely,
Found that the DialogWindow solved the problem mentioned, but it wasn't a complete solution. Refer to: WPF modal window in Visual Studio Extension blocking input.
Related
I've ran into a weird bug where a WPF app is closing after the first window closes. This has made me curious what is triggering it to close
For example this is what I was the unworking version. After the EULAWindow would close it would shut down the application.
EULAWindow eula = new EULAWindow();
eula.ShowDialog();
MainMenuWindow mainWindow = new MainMenuWindow();
mainWindow.ShowDialog();
I thought it would open the EULA and then open the Menu window. I've found that if I rearranged the code it will operate like expected.
For example this will fix it:
EULAWindow eula = new EULAWindow();
MainMenuWindow mainWindow = new MainMenuWindow();
eula.ShowDialog();
mainWindow.ShowDialog();
This brings me to the question of what actually is causing the application to shut down in the first situation?
ShowDialog() is a blocking call. So, in the first case you have single window, then show it, then let user to close it. What should an app to do once last UI window is closed? Maybe, follow to app shutdown code? I suspect so.
In the 2nd case you create two windows before the blocking inside ShowDialog(). So, once you closed the first window, there is another one that could accommodate the user, and the app is not shutting down, it just waits for the next window to be shown.
Since I was using Application Startup to create my windows, it was defaulting setting the EULAWindow to the Current.MainWindow Then keeping the Current.ShutDownMode as ShutdownMode.OnMainWindowClose.
When you create two windows, before calling Show or ShowDialog, it changes the shutdown mode automatically to ShutdownMode.OnLastWindowClose
I'm not certain how or where this happening, but I can tell this is the behavior that is happening upon further investigation.
I've found this behavior here whilst searching for a way to open/close windows in viewmodels. I implemented the behavior more or less exactly as stated in that answer, except that I changed the inherited Behavior<UserControl>to Behavior<Window>, as I used the behavior in a Window and not a UserControl.
Everything worked well until I tried to change the window.Show() to a dialog window.ShowDialog(). After closing the newly opened window, it would not reopen again.
I figure that has something to do with the way dialogs work?
Is there a way I can change that behavior so it would work with dialogs as well?
(Or did I actually make a mistake implementing it, causing it not to fully function? (In case it works for other people))
How can I show a dialog message, similar to MessageBox, which have just the "Cancel" button and can be closed by the application.
The idea is to show the dialog while the application retrieves data from a server, allowing the user to cancel this request, and closing the dialog once the request is completed.
I recall having a very similar problem in the past. I don't think there is a dialog message "out of the box" that works like that. The way I solved this was by writing a class that modeled this sort of behavior in a window and having the application spawn an instance of the window.
The silverlight message box blocks code execution while it is open so it is not possible to close it. However you can use an XNA messagebox in Silverlight which is asynchronous
This explains its use in depth
You can probably then call EndShowMessageBox for your purposes.
if your intention is to let the user know that something is loading and that they should wait. you should use a progressbar instead.
How to: Create a Custom Indeterminate Progress Bar
Goal:
Enable closing of the application's window(s) independently without affecting others. The application is created in WPF.
Problem:
Can't close the window(s)
In winform, it is enough to have the code winform.close() to close down the window but it doesn't work in WPF.
You can have this code to close a specfic window:
Application.Current.Windows[0].Close();
but how would it work if you have many windows and you want to close a specific window without affecting the others?
Use the Application class to get the windows through Application.Windows-property exactly as you described. If you are in the code-behind of the window, call this.Close();
Configuration for multiple Windows
Set the main window to the Application.MainWindow property and set the Application.ShutdownMode to a appropriate value if you also want to hold the app open, if the main window is closed (e.g App.Current.ShutdownMode=ShutdownMode.OnExplicitShutdown; ).
I have already observed, that some people have had problems with the ShutdownMode. A workaround for this is to open the first window invisible and from this window, you open the visible application windows. This prevents the application from closing if the first created window will be closed. However you should be able to resolve this problem also over the ShutdownMode-property.
In scenarios with multiple windows, you can use Shutdown to close the app without closing every window.
I hope this answer is what your question is about. Make a comment if not.
I am agree with HCL. You can use this.Close(); from code-behind of the window, this will close WPF window as like winform.close();.
Or you can use following code for get the specific window for close
Window win = Application.Current.Windows.OfType<Window>().SingleOrDefault(w => w.Name == "Window Name");
win.Close();
just use this code to close the most recent window
Application.Current.Windows[Application.Current.Windows.Count - 1].Close();
I am attempting to write a specialized onscreen keyboard (OSK) for an application I'm writing in C#. To facilitate this, I've created a form which has several buttons on it representing keys, and clicking them calls SendKeys and sends out the appropriate keys.
This form is owned by the main window that is shown when the application first starts, using the Owner property. This way, the OSK pops up whenever the user focuses the application, and it stays on top of the main window if it said main window is dragged over it.
This all works great, but because I have modal dialogs that I also want to use with the OSK, I attempted to create it in a separate thread, complete with its own message loop (via Application.Run) so it could still be usable with any modal dialogs in the main thread.
The problem with this is that, obviously, being in a separate thread can cause InvalidOperationExceptions because of cross-threaded calls. One specific example of this is when calling Application.Run(osk) from the new thread, a cross thread error occurs because it is attempting to update the window's handle with the owner (the main window).
My question is, is it possible to have an owned form on a thread that is separate from the owner in a safe manner? And, if failing that, is it possible to emulate an owned form's characteristics (namely being Always On Top for only the main window, and popping up when the main window is focused)?
Thanks, and sorry if this is confusing.
I think this is actually a bug in Windows Forms. Somewhat inevitable due to the way it checks for access to the Handle property by the wrong thread. The SDK docs for SetParent are not explicit about it, it states the requirement is that both windows belong to the same application. No mention of having to belong to the same thread. I know for a fact that the 'same application' requirement is not hard, there's appcompat code in Windows that makes this work for windows from different processes. Adobe Acrobat ab/used this for a long time. Which definitely absolves the 'same thread' requirement.
Well, punt the problem and try it out. Set Control.CheckForIllegalCrossThreadCalls to false before you set the owner, back to true afterward. And test the heck out of it. If you have trouble then try pinvoking SetParent() directly instead of setting the Owner. Windows Forms actually uses SetWindowLongPtr which is not recommended by the SDK.
I'll take a stab at this. Try running the OSK as a separate process.
Try using ShowDialog for the OSK as well instead of Application.Run - ShowDialog creates a message loop and ends it when the window is closed, and perhaps will solve your problems.
new Thread(() => new OSK().ShowDialog());
Why not use Control.Invoke to make cross-threaded calls to avoid InvalidOperationException?