如何从ViewModel关闭视图?
我有一个WPF窗口,它定义了多个Regions并用作Shell来托管我的应用程序的视图。我希望View能够从Region中删除自己,或者从标签容器中关闭它。如何从ViewModel中完成此行为。
答案 0 :(得分:7)
由于ViewModel
没有(且不应该)引用View
,因此您无法直接关闭它。但是,您可以在Event
中添加ViewModel
来表明它想要关闭。
Josh Smith写了an article来说明如何做到这一点(大约在文章的一半)。
答案 1 :(得分:5)
这实际上取决于您的应用程序架构,但这是我如何使用Prism。
首先我要说的是,只要它不是View的具体实现,即接口引用,就让你的VM引用View是 ok 。
我使用依赖注入将View和ViewModel结合在一起,非常类似于在StockTraderRI中完成的方式。所以我有一个IView和一个IViewModel。 IViewModel有一个名为“View”的IView类型。
从适用于您所在地区的代码层(对我来说,通常是控制器...请参阅StockTraderRI)中,添加机制以从区域中删除您的视图。
例如:
myRegion.Remove(myIViewModel.View);
如果区域由控制器处理,您可能希望在VM上放置一个简单事件,以便在VM想要“关闭”时通知。如果您希望使用弱事件模型,也可以尝试使用IEventAggregator。如果在VM中处理该区域,只需在那里添加该代码即可。
答案 2 :(得分:3)
这是我的登录模块的样子:
public class LoginModule : IModule
{
private readonly IUnityContainer container;
public LoginModule(IUnityContainer container)
{
this.container = container;
}
#region IModule Members
public void Initialize()
{
this.container.RegisterType<ILoginController, LoginController>(new ContainerControlledLifetimeManager());
this.container.RegisterType<ILoginView, LoginView>();
this.container.RegisterType<ILoginViewModel, LoginViewModel>();
ILoginController controller = this.container.Resolve<ILoginController>();
controller.Run();
}
#endregion
}
这是控制器:
public class LoginController : ILoginController
{
private readonly IRegionManager regionManager;
private readonly ILoginViewModel model;
public LoginController(IRegionManager regionManager, ILoginViewModel model)
{
this.regionManager = regionManager;
this.model = model;
model.RequestClose += new EventHandler(model_RequestClose);
}
void model_RequestClose(object sender, EventArgs e)
{
regionManager.Regions["LoginRegion"].Remove(model.View);
}
#region ILoginController Members
public void Run()
{
// Register views here
regionManager.Regions["LoginRegion"].Add(model.view);
}
#endregion
}
这是我的ViewModel:
public class LoginViewModel : ViewModelBase, ILoginViewModel
{
IEventAggregator _eventAggregator;
RelayCommand _loginCommand;
private readonly UserProfileRepository _userProfileRepository;
public event EventHandler RequestClose;
public ICommand LoginCommand
{
get
{
if (_loginCommand == null)
{
_loginCommand = new RelayCommand(
param => this.Login(),
param => this.IsValid());
}
return _loginCommand;
}
}
public LoginViewModel(IEventAggregator eventAggregator, UserProfileRepository userProfileRepository, ILoginView view)
{
this._eventAggregator = eventAggregator;
this._userProfileRepository = userProfileRepository;
this.View = view;
}
#region ILoginViewModel Members
public ILoginView View { get; private set; }
#endregion
}