在Caliburn.Micro中管理ViewModel

问题描述 投票:0回答:1

我正在使用Caliburn.Micro Framework将正在开发的应用程序更改为MVVM模式。

[由于我已经习惯了,起初,我通过继承MainViewModel的IConductor,然后使用ActivateItem方法在屏幕上导航,使用Conductor<object>接口进行导航。

我没有使用容器,而是每次都实例化一个新的ViewModel。

例如,要导航至FirstViewModel,我使用的是ActivateItem(new FirstViewModel());

ViewModelels的资源有限,因此该实现并不引人注目。但是,我发现ViewModel实例没有被处置,并且我开始使用Timers检查该实例是否仍在运行,并在后台堆积。

从那时起,我一直在尝试各种实现来控制ViewModel的管理方式。我想要的是能够决定是引用已经实例化的ViewModel还是实例化一个新的ViewModel。另外,我想决定是否放置ViewModel或使其保持运行状态,以便以后重新连接到它。

所以,阅读文档,我已经在BootStrapperBase中实现了SimpleContainer

public class Bootstrapper : BootstrapperBase
    {
        private SimpleContainer _container = new SimpleContainer();
        public Bootstrapper()
        {
            Initialize();
        }

        protected override void Configure()
        {
            _container.Instance(_container);
            _container
                .Singleton<IWindowManager, WindowManager>()
                .Singleton<IEventAggregator, EventAggregator>();

            GetType().Assembly.GetTypes()
                .Where(type => type.IsClass)
                .Where(type => type.Name.EndsWith("ViewModel"))
                .ToList()
                .ForEach(viewModelType => _container.RegisterPerRequest(viewModelType, viewModelType.ToString(), viewModelType));

        }
        protected override object GetInstance(Type service, string key)
        {
            var instance = _container.GetInstance(service, key);
            if (instance != null)
                return instance;
            throw new InvalidOperationException("Could not locate any instances.");
        }

        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            return _container.GetAllInstances(service);
        }
        protected override void BuildUp(object instance)
        {
            _container.BuildUp(instance);
        }

        protected override void OnStartup(object sender, StartupEventArgs e)
        {

            DisplayRootViewFor<ShellViewModel>();   

        }
    }

我以为IoC.Get<FirstViewModel>()会实例化一个新的ViewModel或重用一个已打开的ViewModel,如果它已被实例化。但是,它每次都实例化一个新的ViewModel。

而且,我无法弄清楚在激活另一个模型时如何处理ViewModel。例如,我在第一个ViewModel上放置了一个OnDeactivate,该OnDeactivate在切换到另一个ViewModel时触发,但是我不知道应该放置什么代码来处理该实例。我尝试了此安装程序,实现了IDisposable接口,但收到了System.StackOverflowException。

protected override void OnDeactivate(bool close)
        {

            Dispose();
            Console.WriteLine("deactivated");
        }
public void Dispose()
        {
            base.TryClose();
        }

Caliburn的SimpleContainer.Micro是否足以管理ViewModel,还是我应该研究其他方法?

我知道我似乎在问多个问题,但所有这些问题都与管理视图模型有关的一个主要问题有关。

阅读文档时,我遇到了Lifecycle概念,我认为这是可以解决我的问题的概念,但是我没有找到进一步的解释。

Caliburn.Micro上的文档没有提供很多示例,我发现很难理解如何在没有示例的情况下正确使用此框架。

c# wpf mvvm caliburn.micro
1个回答
0
投票

因此,如果您想实例化您的选择,可以为此使用一个助手:(一些知识需要反思)

public static class HelperConstructor
{
    public static T MyCreateInstance<T>(Dictionary<string, object> defaultvalues)
        where T : class
    {
        return (T)MyCreateInstance(typeof(T), defaultvalues);
    }

    public static object MyCreateInstance(Type type, Dictionary<string, object> defaultvalues)
    {
        var ctor = type
            .GetConstructors()
            .FirstOrDefault(c => c.GetParameters().Length > 0);


        return ctor != null
            ? ctor.Invoke
                (ctor.GetParameters()
                    .Select(p =>
                        p.HasDefaultValue ? p.DefaultValue :
                        p.ParameterType.IsValueType && Nullable.GetUnderlyingType(p.ParameterType) == null
                            ? Activator.CreateInstance(p.ParameterType)
                            : null
                    ).ToArray()
                )
            : Activator.CreateInstance(type);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.