我是MVVM和IoC的新手。我为此项目使用ViewModel-first方法。我的项目程序集组织如下所示:
View
(已引用ViewModel
)
ViewModel
(已引用Model
)
Model
一开始工作正常,直到需要Login
视图。 Login
在程序启动时运行。成功登录后,将显示MainWindow
,Login
必须自行关闭。可以使用LogoutCommand
中的MainWindow
进行相反的操作。
我面临的主要障碍是为给定的View
类型实例化ViewModel
(窗口),而ViewModel
不知道其View
。在寻找答案时,我发现:
MessageBox
。但是仅出于此目的,我不习惯使用这种模式来处理对象实例化。SimpleIoc
实例注入到View
构造函数作为接口并尝试在ViewModel
ViewModelLocator
用作启动器,进行了尝试。
SimpleIoc.Default.Register<IMainWindowView, MainWindow>();
SimpleIoc.Default.Register<ILoginView, Login>();
SimpleIoc.Default.Register<LoginVM>();
SimpleIoc.Default.Register<MainWindowVM>();
成功登录后,显示MainWindow
并关闭Login
。但是,当我注销MainWindow
以再次显示Login
时,我遇到了InvalidOperationException Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed.
,因此我认为我需要通过在Window上注销来“清理”由SimpleIoC
创建的实例闭幕活动。
public class ViewModelBaseEx : ViewModelBase
{
protected SimpleIoc Ioc
{
get { return SimpleIoc.Default; }
}
protected virtual void Unregister<T>() where T : class
{
Cleanup();
if (Ioc.IsRegistered<T>())
{
// Attempt to remove instance
Ioc.Unregister<T>();
// If i still need to show this window again,
// shouldn't i need to have this instance available? (not sure)
Ioc.Register<T>();
}
}
}
A,上述解决方法不起作用,现在我不知道该怎么办。
更新
取消注册后似乎需要注册,因为如果仅保留未注册的类型,则找不到该类型。至于问题,似乎我也需要注销View
类型。因此,我在View
(窗口)
private void MainWindow_Closed(object sender, EventArgs e)
{
SimpleIoc.Default.Unregister<IMainWindowView>();
SimpleIoc.Default.Register<IMainWindowView, MainWindow>();
}
到目前为止效果很好,这种方法可以接受吗?