【问题标题】:Best place to create a ViewModel in MVVM [closed]在 MVVM 中创建 ViewModel 的最佳位置 [关闭]
【发布时间】:2012-09-12 03:05:51
【问题描述】:

我有一个问题:在 MVVM 中创建 ViewModel 的最佳位置在哪里以及如何创建?

1) 在 App.xaml.cs 中创建一次作为静态字段,然后通过 App 使用?

2) 当我导航到这个页面时,总是在 Page.cs 中创建新的 ViewModel?

3) 其他选项

【问题讨论】:

  • 我一直看到它与视图创建密不可分。

标签: wpf mvvm viewmodel virtual-machine


【解决方案1】:

在 MVVM 中,ViewModel 应用程序。这意味着我通常有一个启动 ViewModel 作为我的应用程序的入口点,我通常在 App.xaml.cs OnStartup 代码中创建它的一个实例

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    var app = new ShellView();
    var context = new ShellViewModel();
    app.DataContext = context;
    app.Show();
}

每隔一段时间,我都会有一个应用程序在启动窗口的构造函数中创建 ViewModel,但这并不是真正的首选,因为这意味着如果我有任何启动逻辑,我必须将它放在代码隐藏View 也是如此,我不喜欢在我的 View 层中混合应用程序逻辑。

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ShellViewModel();
    }
}

无论您如何操作,请记住,在使用 MVVM 时,您的 ViewModel 是您的应用程序,而不是您的 View,因此通常您的 ViewModel 以某种方式连接到启动 ViewModel。视图只是用户与您的应用程序(ViewModel)交互的一种用户友好方式。

【讨论】:

  • 当有许多不同 ViewModel 的视图时,这是如何工作的?您的 OnStartup 方法是否设置了所有 DataContext?创建新视图时会发生什么?
  • 嗨阿德里安,通常我只像这样连接主要的ShellViewShellViewModel。我告诉 WPF 如何通过在某个应用程序的 .Resources 中放置一个隐式的 DataTemplate 来绘制其余的 ViewModel。当 WPF 去绘制一个 ViewModel 时,它会检查是否有一个 DataTemplate 它应该用来绘制那个 ViewModel,如果有,就使用它。
  • 感谢瑞秋。我需要同事的帮助来解压它,因为我曾想象 DataTemplates 只能与 ItemsControls 一起使用。
【解决方案2】:

有不同的方法可以做到这一点,取决于你的想法。

我个人总是有一个类用于创建我需要的所有对象,在App.xaml.cs 中调用。 该类基本上会在显示启动画面时执行那些耗时的启动过程。我在这里创建视图和视图模型并链接它们

这让我只有一个点来创建所有这些 View-to-ViewModel 链接,即使我添加/删除某些东西,我也可以轻松地回到它。

我不喜欢在每个视图的构造函数中初始化 viewModel 的方法。假设您的项目中有 15 个视图,如果您想检查所有 ViewModel 初始化,您将有 15 个不同的文件可供浏览。

这是我对此的谦虚参与=)

【讨论】:

    【解决方案3】:

    您可以使用依赖注入并像这样创建它(假设您正在使用一些 DI 容器):

     public partial class YourView : UserControl
    {
        public YourView (IYourViewModel viewModel)
        {
            InitializeComponent();
            this.DataContext = viewModel;
        }
    }
    

    【讨论】:

    • 我也会这样做。但是,假设您需要显示另一个 UserControl 或 YourView 中的 Dialog,您将如何在不传递您的 DI 容器的情况下为他们提供 ViewModel?
    • 只要容器注册了它们,它们就可以被注入到它们的构造函数中。另一种选择可能是让 YourView 传递一些东西或在其他选项上设置一个属性?
    • 是的,但是将视图注入 ViewModel 会创建对我试图避免的表示层的依赖。在 ViewModel 中引发某种事件并让一些外部实例(可能是控制器)创建并显示需要显示的 View 怎么样?
    • 我并不是说将视图注入到视图模型中。至于事件,我认为您可以引发一个事件,也许使用视图模型作为有效负载,然后从中加载用户控件。
    • 啊抱歉,我误会你了。你的意思是通过YourView的构造函数注入YourView应该打开的View吗?
    猜你喜欢
    • 1970-01-01
    • 2021-08-30
    • 2018-11-19
    • 2016-09-04
    • 1970-01-01
    • 2012-01-15
    • 2011-02-25
    • 2010-12-13
    相关资源
    最近更新 更多