使用 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)的映射。
我是 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)的映射。