【问题标题】:Custom caliburn.micro splashscreen with shell screen conductor带有外壳屏幕导体的定制 caliburn.micro 防溅屏
【发布时间】:2014-09-28 06:07:36
【问题描述】:

我是 WPF 和 Caliburn.micro 的新手,我想使用 Caliburn 为 WPF 应用程序实现自定义启动画面。 我正在寻找使用屏蔽导体的正确方法(据我所知,这是最好的解决方案)。

我的引导程序看起来像这样:

public class AppBootstrapper : BootstrapperBase
    {
        private bool actuallyClosing;
        private CompositionContainer container;        

        public AppBootstrapper()
        {
            Start();
        }

        protected override void Configure()
        {
            container = new CompositionContainer(
                    new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>())
                );

            var batch = new CompositionBatch();

            batch.AddExportedValue<IWindowManager>(new WindowManager());
            batch.AddExportedValue<IEventAggregator>(new EventAggregator());
            batch.AddExportedValue(container);
            container.Compose(batch);
            Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
        }

        protected override object GetInstance(Type serviceType, string key)
        {
            string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
            var exports = container.GetExportedValues<object>(contract);

            if (exports.Any()) return exports.First();
            throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
        }

        protected override IEnumerable<object> GetAllInstances(Type serviceType)
        {
            return container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
        }

        protected override void BuildUp(object instance)
        {
            container.SatisfyImportsOnce(instance);
        }

        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            DisplayRootViewFor<ShellViewModel>();
        }
    }

ShellViewModel 是这样的:(但我实际上并不想看到它的窗口)

[Export(typeof(ShellViewModel))]
public class ShellViewModel : Conductor<Screen>
{
    [ImportingConstructor]
    public ShellViewModel()
    {
         ActivateItem(new SplashScreenViewModel());
         int i = 10; // loading ... or do the loading inside the splashscreen ??
         ActivateItem(new MainWindowViewModel());
    }
}

SplashScreenViewModel 非常简单:

[Export(typeof(SplashScreenViewModel))]
    public class SplashScreenViewModel : Screen
    {
        private string appName;
        private string version;
        private string service;
        private string creator;
        private string copyright;
        private string message;

        [ImportingConstructor]
        public SplashScreenViewModel()
        {
            appName = Assembly.GetEntryAssembly().GetName().Name;
            version = Assembly.GetEntryAssembly().GetName().Version.ToString();
            copyright = "Copyright © corp 2014";
            service = "Department";
            creator = "user - " + Service;
            message = "Loading ...";
        }
    }

最后是 MainWindowViewModel :

[Export(typeof(MainWindowViewModel))]
public class MainWindowViewModel : Screen, IGuardClose
{
    [ImportingConstructor]
    public MainWindowViewModel()
    {
        NetworkUpdate(); // do stuff.
    }
    void IGuardClose.CanClose(Action<bool> callback)
    {
        throw new NotImplementedException();
    }

    void IClose.TryClose()
    {
        throw new NotImplementedException();
    }
}

现在我正在尝试每一种方法,但它要么什么都不显示,要么只显示主窗口,要么只显示启动画面,甚至是 shellview 的空视图......

我真的很感激这方面的一些提示!

谢谢大家...

【问题讨论】:

    标签: c# wpf mvvm splash-screen caliburn.micro


    【解决方案1】:

    不要将 ActivateItem 用于启动画面。

    根据我对启动的理解,最好使用 WindowManager(在 exe 加载所有必要进程时显示弹出窗口)

    您可以在 OnStartUp 的 Appbootstrapper 中进行操作

    protected override void OnStartup(object sender, StartupEventArgs e)
        {
            var splash = this.container.GetExportedValue<SplashScreenViewModel>();
            var windowManager = IoC.Get<IWindowManager>();
            windowManager.ShowDialog(splash);
    
           // do your background work here using
            var bw = new BackgroundWorker();
            bw.DoWork += (s, e) =>
                {
                    // Do your background process here
    
                };
    
            bw.RunWorkerCompleted += (s, e) =>
                {
                    // close the splash window
                    splash.TryClose();
                    this.DisplayRootViewFor<ShellViewModel>();
                }; 
    
            bw.RunWorkerAsync();           
        }
    
    
        // your ShellViewModel
        [ImportingConstructor]
        public ShellViewModel(MainViewModel mainViewModel)
        {
            this.DisplayName = "Window Title";
            // no need to new
            this.ActivateItem(mainViewModel);
        }
    

    【讨论】:

    • 你好 Amin,我现在正在看,我会试一试。我会尽快回复您,但您的回答仍然很好!
    • 提供和接受的答案有问题。永远无法到达后台工作人员。如果您将 windowmanager.ShowDialog(splash) 放在 bw.RunWorkerAsync 之后,它可以工作,但应用程序只是退出......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多