我有一个MainWindow
,它有自己的ViewModel
,我想用它来进行导航。它看起来像这样:
public MainWindowViewModel()
{
SelectedViewModel = new LoginViewModel();
DashboardCommand = new DelegateCommand(OpenDashboard);
}
private object _selectedViewModel;
public object SelectedViewModel
{
get => _selectedViewModel;
set
{
_selectedViewModel = value;
OnPropertyChanged("SelectedViewModel");
}
}
public ICommand DashboardCommand { get; set; }
private void OpenDashboard(object obj)
{
SelectedViewModel = new DashboardViewModel();
}
我有一个LoginView
,其中包含UserControl
个简单表单,用户可以输入详细信息,然后点击Button
进行登录。当用户点击Button
时,会执行检查,如果通过,我想从DashboardView
导航到LoginViewModel
。这是LoginViewModel
:
#region Login
private DelegateCommand _loginCommand;
public ICommand RegisterCommand
{
get
{
_loginCommand = new DelegateCommand(param => Login());
return _loginCommand;
}
}
private void Login()
{
if (LoginCheck())
{
// TODO: Navigate to the DashboardView
}
}
#endregion
我的问题是如何从MainWindowViewModel
LoginViewModel
答案 0 :(得分:1)
您的案例是何时在MVVM中使用消息传递的一个很好的例子。
执行检查并通过后,您应该从LoginViewModel发送消息。 MainWindowViewModel应该注册此消息并进行导航。
要使用消息传递,您可以使用发布/订阅模式。要做到这一点,你不必实现它。您可以使用几个实现的MVVM库。
例如,您可以使用MVVM Light:
从ViewModelBase
继承您的ViewModel,然后您可以使用MessengerInstance
发送和注册消息。
传递检查时您在LoginViewModel中的代码:
MessengerInstance.Send(new NavigateToViewNotification(){ToView="Dashboard"});
您在MainWindowViewModel中的代码(在consturctor中):
MessengerInstance.Register<NavigateToViewNotification>(this, ntv=> {/* here imlement the navigation ntv.ToView has the info to which view*/});
NavigateToViewNotification
是你自己的班级:
public class NavigateToViewNotification
{
public string ToView { get; set; }
}
这样就可以避免在ViewModel之间直接引用,从而导致松散耦合的ViewModel,从而更容易维护客户端代码。
答案 1 :(得分:1)
我的问题是如何从LoginViewModel导航MainWindowViewModel?
三个选项。
保留对MainWindowViewModel
LoginViewModel
的强烈引用,例如在创建前者时将前者注入后者的实例:
public LoginViewModel(MainWindowViewModel vm)
{
_vm = vm;
}
这会在两种类型之间创建一个强耦合,或者更确切地说是应该能够导航的任何子视图模型类型和MainWindowViewModel
。
LoginViewModel
发送到MainWindowViewModel
:https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/。这消除了视图模型类型之间的强耦合,但使代码更复杂,因为不再直接引用导航发生的MainWindowViewModel
。
LoginViewModel
只是使用事件聚合器引发事件,然后它并不真正关心谁(如果有的话)实际处理该消息并执行实际导航。
MainWindowViewModel
。这使得所有视图模型彼此松散耦合。他们只了解并依赖共享服务。