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

时间:2019-07-07 20:35:17

标签: c# wpf mvvm prism dryioc

我是WPF / MVVM的新手,并且我正在一个项目中集成了Dragablz选项卡控件,因此我需要等效于new OEEView()的实例化到内容的新窗口新标签页对象的区域。

但是,在我正在使用的视图的目录(OEEView)中,它需要传递给它的viewModel。我尝试在选项卡实例化代码中创建一个新的OEESelectionViewModel并将其传递给新的OEEView(),但其默认ctor看起来像public OEESelectionViewModel(IDialogService dialogService, IOEELogger oeeLogger, ISettingsManager settingsManager),我不确定如何传递这些I对象。根据我的收集,这是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"

2 个答案:

答案 0 :(得分:0)

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

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

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

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

当然,如果您想超纯净,还可以通过DI容器解析和创建视图。
解析接口的具体实例时,DI容器将创建该实例,并自动解析(并创建)构造函数中指定的依赖项。那就是使用DI框架之美的一部分-一旦注册了映射,魔术就会发生。使用IOC模式和DI容器可以消除很多重复的复杂性。

答案 1 :(得分:0)

  

但是,在我正在使用的视图(OEEView)的中心,它需要一个viewModel传递给它。

不,不是。那是不好的风格,应该作为最后的手段。除非您确实遇到特殊情况,否则视图通过xaml的绑定唯一地连接到​​视图模型。

您要使用的是附加的ViewModelLocator.AutowireViewModel=true属性。这样可以确保为视图分配了一个可解析的视图模型,而无需在代码中添加任何内容。

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