views:

52

answers:

3

If I use Application.LoadComponent() to load a UserControl, Page or Window, my application freezes when I try to close it.

The app apparently closes, but the process keeps running. Easy to notice when debugging.

I've tested it under Windows 7 64bit and Vista 32bit. In both cases I have used VS2008 and .NET 3.5.

A repro can be built by creating a wpf application as follows:


    public partial class Window1 : Window {
        public Window1() {
            InitializeComponent();
        }
        public void LoadCopy() {
            var uri = new Uri("/WpfApplication1;component/window1.xaml", UriKind.Relative);
            var copy = (Window)Application.LoadComponent(uri);
            MessageBox.Show(copy.Title);
        }
        private void Button_Click(object sender, EventArgs e) {
            LoadCopy();
        }
    }

Does anyone know what might be happening? And how to solve it?

A: 

I have build you application on Windows 7 32bit under .Net 4.0 and 3.5. I works fine for me. I think you problem is configuration specific. Which configuration do you have? Do you reference any assemblies except default WPF project references?

Andrey Gordeyev
The code I've posted reproduces the error in Windows 7 64bit and Vista 32 bits, both cases under .NET 3.5 and VS2008.
Rafael Romão
+1  A: 

Try assigning the owner to the created assembly i.e. copy.Owner = this;

I was able to close your example after doing this.

Mark Hall
Perfect! Probably this will avoid the loop Mrk Mnl mentioned by removing the window from the application's children. Just a guess. Can you comment how did you find this solution?
Rafael Romão
I ran into a similar issue when I was converting a Win Form application to WPF. The windows that I was creating using CenterOwner for the window state were not behaving correctly. After I added the creating application as owner it took care of it.
Mark Hall
+1  A: 

I think it is because you are calling LoadComponent() on what is also your Main Window ( http://msdn.microsoft.com/en-us/library/system.windows.application.mainwindow.aspx ), i.e. the startup uri, in your case Window1. The program is probably entering some loop when you close it because closing a Main Window by default shuts down the Application and your two instances of Window1 are waiting on each other (A.K.A. a deadlock)! Albeit seemingly only after making the Application invisible (so it seems to have closed).

If you still must use use LoadComponent() on Window1 I think you would need to not make it your startup uri by changing the StartupUri of your Application:

<Application
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 StartupUri="Window1.xaml"> <!-- change this -->
</Application>

Or change Application.ShutdownMode ( http://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode.aspx ) to OnLastWindowClose:

<Application
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 StartupUri="Window1.xaml"
 ShutdownMode="OnLastWindowClose">
</Application>
Mrk Mnl
Good answer. Probably explains what is happening, but none of your solutions is possible for me. Thanks anyway.
Rafael Romão
Hmm.. I think I may be wrong.. (it was just a guess).. If the copied window is not automatically owned by your application (I assumed it was) or any windows therein then that would explain why the program persisted after everything else was closed (though I would have thought the unclosed window would remain visible then)...
Mrk Mnl