Prism2 / MVVM Закрыть представление из ViewModel - PullRequest
5 голосов
/ 13 сентября 2009

Как закрыть вид из его ViewModel?

У меня есть окно WPF, которое определило несколько областей и используется в качестве оболочки для размещения представлений для моего приложения. Я хотел бы, чтобы View мог удалить себя из региона или закрыть его из контейнера с вкладками. Как я могу выполнить это поведение из ViewModel.

Ответы [ 3 ]

7 голосов
/ 13 сентября 2009

Поскольку ваша ViewModel не имеет (и не должна иметь) ссылку на View, вы не можете закрыть ее напрямую. Однако, что вы можете сделать, это добавить Event в ваш ViewModel, чтобы указать, что он хочет быть закрыт.

Джош Смит написал статью , показывающую, как это сделать (примерно в середине статьи).

5 голосов
/ 14 сентября 2009

Это действительно зависит от архитектуры вашего приложения, но вот как я это делаю с Prism.

Во-первых, я хочу сказать, что ок позволяет вашей виртуальной машине ссылаться на представление, если оно не является конкретной реализацией представления, то есть ссылается на интерфейс.

Я женюсь на View и ViewModel, используя внедрение зависимостей, очень похожее на то, как это делается в StockTraderRI. Итак, у меня есть IView и IViewModel. IViewModel имеет свойство с именем «View» типа IView.

В слое кода (для меня обычно это контроллер ... см. StockTraderRI), который работает с вашими регионами, добавьте механизм для удаления вашего вида из региона.

Например:

myRegion.Remove(myIViewModel.View);

Если регионы обрабатываются контроллером, вы можете захотеть поместить простое событие в ВМ, чтобы уведомить, когда ВМ хочет быть «закрытой». Вы также можете поэкспериментировать с IEventAggregator, если вы хотите использовать слабую модель событий. Если регион обрабатывается в виртуальной машине, просто добавьте туда этот код.

3 голосов
/ 14 сентября 2009

Вот так выглядит мой модуль входа в систему:

    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
}
...