WPF Modal dialog closing ends application unexpectedly - wpf

I have a problem with my Application ending unexpectedly when a modal dialog, spawned from the main program window, closes normally. No unhandled exceptions are being thrown and none of the Closing or Closed events are fired on the Main application window.
Essentially I have a main/shell window, which is started in the Application code using ShellWindow.Show(). Through a menu the user can spawn a custom open dialog, this is a new window created and then shown using ShowDialog (the windows owner is set to that of the shell window).
When the dialog is closed (internally, by a command invoking _modalDialogWindow.Close()) the application closes, whereas I would only have expected the modal dialog to have closed.
Debugging the code indicates that the ShellWindow is dumped from memory, as the next executed line of code after _modalDialogWindow.Close() is it falling out of Application.Run() in the static program code.
If anyone has any ideas I am willing to try anything.

It appears that, due to the MVVM/Ioc way I am designing the application window close events are being propagated further than they should. I don't understand this!
However, setting the Application.ShutDownMode to Explicit prevents the app from closing prematurely and I now have the desired behaviour.
Incidentally, turning on all the exceptions as suggested by declyclone didn't yield any exceptions that are thrown internally when then window is closed.

Don't create any windows before you create your application, or they won't get registered properly. They won't show up in Application.Current.Windows or Application.Current.MainWindow. Then when you create your dialog window, your application will think that it is both the MainWindow and the only window.
Example of what not to do:
public partial class App : Application, ISingleInstanceApp
{
MyWindow win = new MyWindow(); //BAD! this is called inside new App(), but before the actual App constructor.
[STAThread]
public static void Main()
{
if (SingleInstance<App>.InitializeAsFirstInstance(Unique))
{
var application = new App();
application.InitializeComponent();
application.Run();
// Allow single instance code to perform cleanup operations
SingleInstance<App>.Cleanup();
}
}
I had this problem too, your answer helped me figure out why.

Related

Open modal dialog in WPF to get credentials for CefSharp

I have a WPF application which is hosting a conversation window from skype for business; the window can open an child control, a Chromiun web browser (CefSharp).
The browser opens a site that needs credentials, so the method GetAuthCredentials is override in order to process the request.
The code goes like this:
AuthBox dlg = new AuthBox();
dlg.Owner = _parent;
dlg.ShowDialog();
callback.Continue(dlg.Username, dlg.Password);
The problem is: I need to make this dialog as modal, in order to lock the parent window (the conversation); for that reason, dlg.Owner = _parent; is added. However this throws an exception:
System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.'
To use dispatcher.BeginInvoke doesn't work.
Is there any other way to open the login window (modal) avoiding this threading issue?
I assume dispatcher.BeginInvoke doesn't work for you because it doesn't block?
Try using a synchronization primitive, such as ManualResetEvent, open the dialog in UI thread, in calling thread wait for ManualResetEvent notification, and make sure dialog raises the event when done.

Starting a WPF application as hidden

I'm writing a WPF application and want it to start as a hidden window. I've created the Window object and set its Visibility property to Visibility.Hidden before calling Application.Run(). Then, I have an event handler for Window.Loaded that also sets the visibility to Visibility.Hidden. Between the call to Application.Run() and the callback to OnWindowLoaded(), there is a black outline of the window that flashes up on the screen and then disappears. It's like the window manager is creating a drop shadow for the window or something and then hides it immediately.
After running my project through instrumentation, I finally found that Window.Show() was somehow getting called. So, I looked into the source code at http://www.dotnetframework.org/Search.aspx:
Application.Run() ends up calling a private method named Application.RunInternal().
RunInternal() checks the visibility of the Window object that was passed in to the Run() method.
If the Visibility property is not Visibility.Visible, a call to Window.Show() is made.
I then looked at the source for System.Windows.Window:
Window.Show() sets the Visibility property on itself (the window) to be Visibility.Visible.
Based on this, I don't see how to force the window to stay hidden. By trying to make the window invisible at startup, I'm causing the Application object to call Window.Show(); I don't understand why the Application object even cares about the window's visibility. It's been a frustrating experience... :-(
I've seen other answers that say to not call Application.Run() and to instead set up your own event dispatchers, but that seems like overkill for something that should be easy. I just want the main window to stay hidden, for no "flicker" to appear at app startup, and for the window to become visible when I'm ready for it to do so (which happens later in my application logic).
Can anyone offer a suggestion?
Did you remove the StartupUri entry in App.xaml? If you do, the App class won't instantiate the window for you and show it. You can do this by yourself by overwriting the App.OnStartup method.
Basically, I build a composition root in this OnStartup method and just create a window at the end of the process:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// Do your custom initialization code here
MainWindow = new MainWindow();
MainWindow.Show();
}
If you really want to omit the whole application build up process (which I wouldn't recommend, as you won't have features like the fallback to Application Resources), you can create a Dispatcher by yourself using this code:
var dispatcher = Dispatcher.CurrentDispatcher;
var synchronizationContext = new DispatcherSynchronizationContext(dispatcher);
SynchronizationContext.SetSynchronizationContext(synchronizationContext);
Dispatcher.Run();
The comment on this Answer finally led me to find the solution to this issue. I needed to display multiple windows on multiple screens at once, and by minimizing the window it gives me the performance I needed. Thanks.

Open a copy of the same window using WPF

I am working with a WPF application.I have two text boxes and a button in my first window.Based on some DB operations i need to open the copy of the first window(if possible open like a new tab) provided both windows can be accessed simultaneously.I used
var MainWindow = new MainWindow();
MainWindow.ShowDialog();
and
var MainWindow = new MainWindow();
MainWindow.Show();
both of them doesnt meet my expectations.Can anyone help me.
When you use ShowDialog(), it opens a single modal dialog that is expected to be closed when complete.
If you want to open multiple windows and not block form control, try using Show() instead.
var window = new MainWindow();
window.Show();
I would advise you to read all of the relating pages on MSDN so that you can learn how everything works.
For the Show method:
Opens a window and returns without waiting for the newly opened window to close.
For the ShowDialog method:
Opens a window and returns only when the newly opened window is closed.
From the Remarks section of the Window.Show Method page:
When the Window class is instantiated, it is not visible by default. Show shows a window and returns immediately, without waiting for the window to be closed. Consequently, the opened window does not prevent users from interacting with other windows in the application. This type of window is called a modeless window. Common examples of modeless windows are properties windows, toolboxes, and palettes. To restrict a user to interacting with a specific window, the window must be opened by calling ShowDialog.
Calling Show achieves the same end result as setting Visibility property of the Window object to Visible. However, there is a difference between the two from a timing perspective.
Therefore, for your solution, I would recommend that you use the Show method instead.

How do I kill a Windows Mobile 6.1 forms app process when the form is closed?

In the Program.cs file of the .Net CF 3.5 WinForms program I've written, I launch the app by instantiating a new instance of Form1.
Application.Run(new Form1());
When I want to close/exit the application, I override the Form1 FormClosed event so that I can ensure exiting the application.
// In Form1 code-behind
private void OnFormClosed(object sender, EventArgs e)
{
Application.Exit(); // Doesn't kill process
}
When this code runs, I want the app to disappear from the screen (close) and I want the process it was running as to die. The app closes (disappears), but unfortunately, the process (we'll call it app.exe) is still running indefinitely. When I start the app again and close it, it spins up another app.exe process, etc. So the process is never dying and more are being created eating memory.
How can I ensure this process is being killed when I close/exit the app? Thanks.
First, you should not have to overide OnFormClosed to get the behavior you're after. Just closing the Form passed in to Application.Run will cause the app's message pump to exit and should cause the process to end. For Windows Mobile you should set the ShowMinimize property of the Form to false to prevent it from just being minimized - you should have a (OK) in the upper right, not an (X).
If the process does not exit when this Form closes, then the culprit 99.99% of the time is that you have a worker thread that is still running preventing the process from closing. Make sure all of your Threads have IsBackground set to true (for CF 3.5) and as a precaution, all of your threads should also have some form of exit notification or flag. Don't rely of the process terminating to tear them down for you.
Your problem is that you have Form.MinimizeBox = true. Change it to false and the form will be closed when ok is clicked instead of minimized when x is clicked.
There are more things to consider in your question:
I override the Form1 FormClosed event
There is no FormClosed event for forms of type System.Windows.Forms.Form, only Closing and Closed.
You don't override an event. You override a virtual function from a base class or interface.

I'm Getting Cannot set Visibility or call Show, ShowDialog Exception

I'm using WAF (Wpf Application Framework) to create a dialog as shown in the ModelView sample application. I am trying to put up a simple AboutBox by mirroring the code for putting up the CreateEmailAccountWizard dialog box. My About box shows up fine the first time, but when I call it again from the menu, it gives me the following exception:
Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed.
First, I don't know what this message means. Second, what am I doing wrong? The sample application doesn't throw this exception when you close and reopen the CreateEmailAccountWizard dialog box. My code is nearly identical to it. Any help would be greatly appreciated.
Never mind. Found the source of the problem. I was creating a singleton from MEF and it was causing the same dialog instance to run twice. I solved the issue by doing the following:
var shellView = _container.GetExportedValue<IShellView>();
_aboutDialogViewModel = _container.GetExportedValue<AboutDialogViewModel>();
_aboutDialogViewModel.ShowDialog(shellView);
I also had to set the MEF attribute on the class to tell it to not use a singleton:
[Export, PartCreationPolicy(CreationPolicy.NonShared)]
public class AboutDialogViewModel : ViewModel<IDialogView>
{
[ImportingConstructor]
public AboutDialogViewModel(IDialogView view) : base(view)

Resources