使用 Prism/MVVM 实例化新的 View/ViewModel 实例

Instantiating a New View/ViewModel Instance Using Prism/MVVM

我是 WPF/MVVM 的新手,我正在开发一个项目,我在其中集成了 Dragablz 选项卡控件,我需要 new OEEView() 的等效项来实例化一个新的Window 进入新选项卡对象的内容区域。

但是,在我使用的视图 (OEEView) 的构造函数中,它需要传递给它的 viewModel。我尝试在选项卡实例化代码中创建一个新的 OEESelectionViewModel 并将其传递给新的 OEEView() 但它的默认 ctor 看起来像 public OEESelectionViewModel(IDialogService dialogService, IOEELogger oeeLogger, ISettingsManager settingsManager) 并且我不确定这些 I-objects 是如何传递的。据我所知,这是 Prism 的责任,并使用依赖注入解决依赖关系。我还尝试为 OEEView 创建一个默认(无参数)构造函数并在其中创建一个新的 OEESelectionViewModel,但我仍然对如何使用 Prism 的 DI 感到困惑。

        public OEEView(OEESelectionViewModel viewModel)
        {
            InitializeComponent();
            DataContext = viewModel;
            _viewModel = viewModel;
        }
        public OEESelectionViewModel(IDialogService dialogService, IOEELogger oeeLogger, ISettingsManager settingsManager)
        {
            ...
        }
        public TabView()
        {
            InitializeComponent();

            var tab = new HeaderedItemViewModel
            {
                Header = new HeaderWithCloseViewModel
                {
                    Header = "OEE Chart #1"
                },
                Content = new OEEView()
            };

            var viewModel = new TabViewModel(tab);

            DataContext = viewModel;
            _viewModel = viewModel;
            this.Show();
        }

我希望能够解析一个新实例并开始使用它,就像我使用 new 关键字一样,但它无法自动解析自己。

_container = new Container();
_container.Register<OEEView>(Reuse.Singleton);
OEEView client = _container.Resolve<OEEView>();

Additional information: Unable to resolve StationControl.ViewModels.OEESelectionViewModel as parameter "viewModel"

通常,您会按照以下步骤操作:

  • 确保您的视图模型实现了一个接口,即 IOEESelectionViewModel
  • 在 DI 容器的类型注册过程中将您的新接口 (IOEESelectionViewModel) 映射(注册)到具体类型 (OEESelectionViewModel)
  • 创建新视图时,使用 IOC (DI) 容器将接口解析为视图模型的具体实例

使用 PRISM 时,解析新具体实例的代码行将如下所示:

var myVM = myIocContainer.Resolve<IOEESelectionViewModel>();
var myView = new OEEView(myVM);

当然,如果你想变得超级纯粹,你也可以通过 DI 容器解析和创建你的视图。
当您解析接口的具体实例时,DI 容器将创建该实例并自动解析(和创建)构造函数中指定的依赖项。这是使用 DI 框架的美妙之处之一——一旦您注册了映射,奇迹就会发生。通过使用 IOC 模式和 DI 容器消除了许多重复的复杂性。

However, in the ctor of the view I'm using (OEEView), it needs a viewModel passed to it.

不,不是。这是糟糕的风格,应该作为最后的手段使用。视图通过来自 xaml 的绑定连接到视图模型,除非您面临真正的特殊情况。

你要做的是使用附带的ViewModelLocator.AutowireViewModel=true属性。这将确保视图神奇地分配了一个已解析的视图模型,而无需在 code-behind.

中放置任何内容

默认情况下有一个约定,但您可以根据需要更改它以适应您的情况。或者您可以为每个视图手动注册从视图到视图模型(-type)的映射。