【问题标题】:Instantiating a New View/ViewModel Instance Using Prism/MVVM使用 Prism/MVVM 实例化新的 View/ViewModel 实例
【发布时间】:2019-07-07 20:35:17
【问题描述】:

我是 WPF/MVVM 的新手,我正在开发一个项目,在该项目中我集成了 Dragablz 选项卡控件,我需要使用 new OEEView() 的等效项将新窗口实例化到一个新的标签对象。

但是,在我正在使用的视图的 ctor (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"

【问题讨论】:

    标签: c# wpf mvvm prism dryioc


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 你能详细说明为什么视图模型应该在这里实现一个接口吗?这是一对一的映射,无论如何,视图永远不会用作单元测试中的测试对象。
    【解决方案2】:

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

    不,它没有。这是不好的风格,应该作为最后的手段。视图通过来自 xaml 的绑定连接到视图模型,除非您遇到非常特殊的情况。

    您要做的是使用ViewModelLocator.AutowireViewModel=true 附加属性。这将确保视图被神奇地分配给已解析的视图模型,而无需在代码隐藏中添加任何内容。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 2020-05-19
      • 2020-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多