【问题标题】:How to create view-model of prism when needed?如何在需要时创建棱镜的视图模型?
【发布时间】:2019-10-18 02:49:09
【问题描述】:

我真的搜索了这个主题并没有找到任何东西,因此我在这里提出问题。
我有一个安装了 Prism 的 WPF 应用程序。
我已按名称约定自动将视图模型与视图连接

<UserControl x:Class="Views.ViewA"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:prism="http://prismlibrary.com/"             
             prism:ViewModelLocator.AutoWireViewModel="True">

和'Model'中的模型是这样的

public class ViewAViewModel {
    public ViewAViewModel () {
         // time-resource consuming operations
    }
}

自动绑定工作完美,没有问题,并且视图及其对应的视图模型匹配,但问题在这里。 我有很多这样的视图说(50),并且对于其中的每一个,视图模型都将使用构造函数来创建耗尽进程。这将使应用程序的启动时间更长,并且它会创建大量的视图模型对象并将它们放入 RAM 中,而不确定它们是否会被使用。

我需要的是在视图被激活时创建视图模型类(我的意思是当视图被导航到时)。这可能吗?如果可以,怎么做?

更新

这是我向模块注册视图的方式,这会导致在模块启动时创建所有视图。

public class Module1 : IModule
{
    public void OnInitialized(IContainerProvider containerProvider)
    {
        var regionManager = containerProvider.Resolve<IRegionManager>();

        regionManager.RegisterViewWithRegion("region1", typeof(View1));
        regionManager.RegisterViewWithRegion("region1", typeof(View2));

有什么方法可以延迟视图的创建,直到导航请求到来?

【问题讨论】:

  • 使用NavigationService 也可以解决您耗时的构造函数。看看 VM InitializeAsync 方法
  • for every one of them, the view-model will be created with constructor exhausting the processes 是什么意思?视图创建时会创建视图模型,为什么启动时创建50个视图?
  • @Haukinger 这真的很有趣,谢谢你让我注意到这个事实。你的评论真的让我想到了另一种思维方式。也许是限制视图构建的更好方法。现在,所有的视图都是在主应用程序启动时创建的,你能给我一些关于延迟创建视图的提示吗?
  • @Haukinger 请查看问题的更新
  • 创建视图通常比视图模型更昂贵。我建议将所有 I/O 和 CPU 昂贵的操作从视图模型的 ctor 移到加载视图时将调用的方法。这样你就不需要为 viewmodel 懒惰的实例化而烦恼。此外,没有视图模型的视图在 MVVM 中有点奇怪,并且可能会在未来引起问题

标签: c# wpf mvvm prism


【解决方案1】:

您可以为每个视图使用导航。 或者您必须为您的视图和视图模型创建一个接口。 一个例子:

public interface IMyView
{
    IMyViewModel ViewModel { get; set; }
}
public interface IMyViewModel
{

}

在模块或 app.cs 中,您应该在 RegisterTypes 方法中注册这些。

containerRegistry.Register<IMyView, MyView>();
containerRegistry.Register<IMyViewModel, MyViewModel>();

您必须在 MyView.cs 类中实现 IMyView 接口。

public partial class MyView : UserControl, IMyView
{
    public MyView(IMyViewModel viewModel)
    {
        InitializeComponent();

        ViewModel = viewModel;
    }

    public IMyViewModel ViewModel 
    {
        get => DataContext as IMyViewModel;
        set => DataContext = value;
    }
}

在你可以使用之后:

public void OnInitialized(IContainerProvider containerProvider)
{
    var regionManager = containerProvider.Resolve<IRegionManager>();

    var firstView = containerProvider.Resolve<IMyView>();

    regionManager.AddToRegion(RegionNames.MainRegion, firstView);
}

在这种情况下,您不应在视图中使用 ViewModelLocator.AutoWireViewModel。

【讨论】:

    猜你喜欢
    • 2021-09-07
    • 2020-10-03
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    相关资源
    最近更新 更多