Prism2 / MVVM从ViewModel关闭视图

时间:2009-09-13 06:05:48

标签: wpf mvvm prism

如何从ViewModel关闭视图?

我有一个WPF窗口,它定义了多个Regions并用作Shell来托管我的应用程序的视图。我希望View能够从Region中删除自己,或者从标签容器中关闭它。如何从ViewModel中完成此行为。

3 个答案:

答案 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
}
相关问题