Weird Issue With Shell Launching Twice

Topics: Prism v2 - WPF 3.5, Prism v2 - WPF 4
Jul 20, 2010 at 2:44 PM
Edited Jul 20, 2010 at 2:49 PM

I have been having this issue since I upgraded to v2.2 of Prism and I can not for the life of me figure out what is happening. Basically my shell will launch with no modules loaded and then after the modules have been loaded will launch again properly, but I still have the first blank shell open. I can close the blank shell and the application continues to run, but if I close the shell with the modules loaded then the application will exit as expected. I created a small video so I could better explain what I am seeing in case I can't quite get it across in words.

http://www.kcdc.org/files/doubleshell.wmv

If I comment out this line view.ShowView(); from the CreateShell() method, shown below, then the first blank shell still launches, but the "good" shell does not. I have no clue where phantom shell is being created more less shown from. I'm pulling my hair out. It has to be something simple, but I have no clue. I've watered it down just about as much as I can. I did create a new test Prism app and I do not experience this issue with it. I used the same bootstrapper and App.xaml.cs logic to launch it's shell, but for some reason it works and this one does not.

Here is my bootstrapper class. 

public class Bootstrapper : UnityBootstrapper
    {
        protected override IModuleCatalog GetModuleCatalog()
        {
            string modulePath = Path.GetFullPath("Modules");
            if (!System.IO.Directory.Exists(modulePath))
            {
                System.IO.Directory.CreateDirectory(modulePath);
            }
            return new MultipleDirectoryModuleCatalog() { ModulePath = modulePath };
        }

        protected override void ConfigureContainer()
        {
            Container.AddExtension(new EnterpriseLibraryCoreExtension());

            Container.RegisterType<IShellView, ShellView>();
            //container.RegisterType<IMessageService, MessageService>(new ContainerControlledLifetimeManager());
            //container.RegisterType<IShowAboutView, ShowAboutViewService>(new ContainerControlledLifetimeManager());
            Container.RegisterType<ILoggerService, EnterpriseLibraryLoggerAdapter>(new ContainerControlledLifetimeManager());
            //container.RegisterType<IUIElementCreationService, WpfCreationService>(new ContainerControlledLifetimeManager());
            //container.RegisterType<IEliteService, EliteDataService>(new ContainerControlledLifetimeManager()); 
            base.ConfigureContainer();
        }

        protected override void InitializeModules()
        {
            IModuleManager manager;

            try
            {
                manager = this.Container.Resolve<IModuleManager>();
            }
            catch (ResolutionFailedException ex)
            {
                if (ex.Message.Contains("IModuleCatalog"))
                {
                    throw new InvalidOperationException(Resources.NullModuleCatalogException);
                }
                throw;
            }
            manager.Run();
        }

        protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
        {
            RegionAdapterMappings regionAdapterMappings = Container.TryResolve<RegionAdapterMappings>();
            if (regionAdapterMappings != null)
            {
                regionAdapterMappings.RegisterMapping(typeof(RadToolBar), Container.Resolve<RadToolBarTrayRegionAdapter>());
                regionAdapterMappings.RegisterMapping(typeof(RadToolBarTray), Container.Resolve<RadToolBarTrayRegionAdapter>());
                regionAdapterMappings.RegisterMapping(typeof(RadPaneGroup), Container.Resolve<RadPaneGroupRegionAdapter>());
                regionAdapterMappings.RegisterMapping(typeof(RadRibbonBar), Container.Resolve<RadRibbonBarRegionAdapter>());
            }

            return regionAdapterMappings;            
        }

        private readonly EnterpriseLibraryLoggerAdapter _logger = new EnterpriseLibraryLoggerAdapter();

        protected override ILoggerFacade LoggerFacade
        {
            get { return _logger; }
        }

        protected override DependencyObject CreateShell()
        {
            ShellViewModel presenter = Container.Resolve<ShellViewModel>();
            IShellView view = presenter.View;

            //view.ShowView();

            return view as DependencyObject;
        }
    }

Here is my App.xaml.cs class.

public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            this.ShutdownMode = ShutdownMode.OnMainWindowClose;
#if (DEBUG)
            RunInDebugMode();
#else
            RunInReleaseMode();
#endif            
        }

        private static void RunInDebugMode()
        {
            AppDomain.CurrentDomain.UnhandledException += AppDomainUnhandledException;
            try
            {
                SplashScreen appSplash = new SplashScreen("../Resources/SplashScreen.png");
                appSplash.Show(false);
                UnityBootstrapper bootstrapper = new Bootstrapper();
                appSplash.Close(TimeSpan.FromSeconds(0.5));

                //InitializeCultures();

                //Resources.MergedDictionaries.Add(ResourceService.GetSharedDictionary(
                //    new Uri(ResourceHelper.SharedResourcePath, UriKind.Relative)));
                Log("Elite Extender is running in Debug Mode", System.Diagnostics.TraceEventType.Information);

                bootstrapper.Run();
            }
            catch (Exception ex)
            {
                Log("Error Starting Elite Extender:" + ex.Message, System.Diagnostics.TraceEventType.Error);
                //HandleException(ex);
            }
        }

        private static void RunInReleaseMode()
        {
            AppDomain.CurrentDomain.UnhandledException += AppDomainUnhandledException;
            try
            {
                SplashScreen appSplash = new SplashScreen("../Resources/SplashScreen.png");
                appSplash.Show(false);
                UnityBootstrapper bootstrapper = new Bootstrapper();
                appSplash.Close(TimeSpan.FromSeconds(0.5));

                //InitializeCultures();

                //Resources.MergedDictionaries.Add(ResourceService.GetSharedDictionary(
                //    new Uri(ResourceHelper.SharedResourcePath, UriKind.Relative)));
                Log("Elite Extender is running in Release Mode", System.Diagnostics.TraceEventType.Information);
                bootstrapper.Run();
            }
            catch (Exception ex)
            {
                Log("Error Starting Elite Extender:" + ex.Message, System.Diagnostics.TraceEventType.Error);
                //throw ex;
                HandleException(ex);
            }
        }

        private static void AppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            HandleException(e.ExceptionObject as Exception);
        }

        private static void HandleException(Exception ex)
        {
            if (ex == null) return;
                Log("Error Occured In Elite Extender:" + ex.Message, System.Diagnostics.TraceEventType.Error);

            //ExceptionPolicy.HandleException(ex, "Default Policy");
            Environment.Exit(1);
        }

        private static void Log(string message, System.Diagnostics.TraceEventType severity)
        {
#if (DEBUG)
            Debug.Print(message);
#else
            LogEntry entry = new LogEntry();
            entry.Severity = severity;
            entry.Message = "App.xaml.cs: " + message;
            entry.Title = "EliteExtender";
            entry.Categories.Add("Core");
            Logger.Write(entry);
#endif    
        }
    }

Any help with this annoying problem would greatly be appreciated!

Jul 20, 2010 at 3:00 PM

OK please disregard this. I would delete it if I could to save public face, but there appears to be no way to do that. :) So I guess I'll use this opportunity to lecture on the issues of copy and paste. Apparently I copied and pasted the App.xaml portion from an older version and forgot to remove the startupuri from it!

<Application x:Class="EliteExtender.Shell.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="Views/ShellView.xaml">

I literally have been looking at this for about 2 hours now and as soon as I posted my question it dawned on me. Talk about over thinking something simple. I could have sworn you guys snuck something in on me in v2.2 that somehow referenced my shell view and was displaying it.

Oh well leasoned learned. Sorry guys and hope this at least puts a smile on someone's face!

Jul 20, 2010 at 4:55 PM

No problem.  Sometimes all it takes to figure out a problem like this is to describe the problem to someone else.

I'm glad you figured it out.

Jul 21, 2010 at 9:13 PM

Same thing happened to me little bit ago...I posted elsewhere though...

 

http://stackoverflow.com/questions/3143283/prism-shell-template-two-instances-of-shellview-being-created

Jul 21, 2010 at 9:34 PM
Haha, thanks for all the support and understanding guys. Glad I'm not alone!