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

正如我习惯的那样,起初,我使用IConductor接口(interface)进行导航,方法是在MainViewModel上继承Conductor<object>,然后使用ActivateItem方法导航屏幕。

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

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

从那时起,我一直在尝试各种实现来控制ViewModels的管理方式。
我想要的是能够决定是引用已经实例化的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时触发的FirstViewModel上放置了一个OnDeactivate,但是我不知道应该放置什么代码来处理该实例。
我已经尝试过此安装程序,实现IDisposable接口(interface),但收到System.StackOverflowException。
protected override void OnDeactivate(bool close)
        {

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

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

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

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

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

最佳答案

SimpleContainer中的RegisterSingleton将完成这项工作...

因此,如果您想实例化您的选择,则可以使用一个帮助程序,在调整代码之后,使用其默认参数检查类型的构造函数:(一些知识需要反射(reflection))。

但是,如果您发现它太复杂,请首先参阅Activator.Createinstance

public static class HelperConstructor
{
  public static T MyCreateInstance<T>()
    where T : class
  {
    return (T) MyCreateInstance(typeof (T));
  }

  public static object MyCreateInstance(Type type)
  {
    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);
  }
}

您通过输入Type来使用此帮助程序:

var instanceviewModel = HelperConstructor.MyCreateInstance(classType);

以后,如果需要,caliburn会自动创建 View 的实例...

关于c# - 在Caliburn.Micro中管理ViewModel,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61540884/

10-11 11:58