Tech Off Post

Single Post Permalink

View Thread: Help with "Improving perceived WPF app startup performance with MEF and a Splash Screen".
  • User profile image
    VcDeveloper

    Well, I couldn't get it to work as I wanted, so I had to result to doing it this way:

    protected override void InitializeModules()
    {
        Shell shellMain = this.Container.GetExportedValue<Shell>();
    
        shellMain.InitializeMainWindow();
    
        TurahStudyUIView view = ServiceLocator.Current.GetInstance<TurahStudyUIView>();
    
        shellMain.Height = 768;
        shellMain.Width = 1024;
        shellMain.WindowStartupLocation = WindowStartupLocation.CenterScreen;
        shellMain.WindowState = WindowState.Maximized;
        shellMain.Activate();
    
        Application.Current.MainWindow = shellMain;
        Application.Current.MainWindow.Content = view;
        Application.Current.MainWindow.Activate();
    }
    

    and put the splash screen in my main window Shell.xaml.cs:

    [Export(typeof(Shell))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public partial class Shell : Window, IPartImportsSatisfiedNotification
    {
        private readonly BackgroundWorker _compositionBackgroundWorker = new BackgroundWorker();
        Loading loading;
    
        public Shell()
        {
            InitializeComponent();
    
            _compositionBackgroundWorker.DoWork += CompositionBackgroundWorker_DoWork;
            _compositionBackgroundWorker.RunWorkerCompleted += CompositionBackgroundWorkerRunWorker_Completed;
        }
    
        public void InitializeMainWindow()
        {
            // Set the Window.Content to the "Loading UI" UserControl
            loading = ServiceLocator.Current.GetInstance<Loading>();
            loading.Show();
    
            _compositionBackgroundWorker.RunWorkerAsync();
        }
    
        private void CompositionBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            this.InitializeModules();
        }
    
        private void InitializeModules()
        {
            IModuleManager manager = ServiceLocator.Current.GetInstance<IModuleManager>();
    
            int maxRecords = 1000;
            for (int x = 1; x < maxRecords; x++)
            {
                System.Threading.Thread.Sleep(5);
                System.Windows.Application.Current.Dispatcher.Invoke((Action)(() => { loading.ViewModel.Status = string.Format("{0}: {1} {2}", "Loading", Convert.ToInt32(((decimal)x / (decimal)maxRecords) * 100), "..."); }));
            }
        }
    
        private void CompositionBackgroundWorkerRunWorker_Completed(object sender, RunWorkerCompletedEventArgs e)
        {
            loading.Hide();
            loading.Close();
            this.Show();
        }
    
        [Import]
        public ShellModel ViewModel
        {
            set
            {
                this.DataContext = value;
            }
            get
            {
                return DataContext as ShellModel;
            }
        }
    
        /// <summary>
        /// Called when a part's imports have been satisfied and it is safe to use.
        /// </summary>
        public void OnImportsSatisfied()
        {
            // IPartImportsSatisfiedNotification is useful when you want to coordinate doing some work
            // with imported parts independent of when the UI is visible.
            Debug.WriteLine("Shell OnImportsSatisfied instantiation");
        }
    }