从Caliburn.Micro、WPF、MVVM的另一个窗口获取信息



我在我的应用程序中基于Caliburn.Micro mvvm框架制作登录窗口。那么,如何从Caliburn.Micro初始化的登录窗口中的TryClose()方法返回属性(例如,如果用户传递了好的数据,则返回true;如果用户传递的凭据不好,则返回false(?如何从IWindowManager.ShowDialog()中打开的窗口中获取信息?

首先,我的MainWindowViewModel.cs:

using Caliburn.Micro;
namespace TaskManager.ViewModels
{
class MainWindowViewModel : Conductor<IScreen>.Collection.OneActive
{
protected override void OnViewLoaded(object view)
{
IWindowManager manager = new WindowManager();
//Login page, context is data with user's lists
LoginViewModel loginView = new LoginViewModel(context);
manager.ShowDialog(loginView, null, null);
//here i want to get info, if i get logged properly or not
}
public void LoadUserInfoPage() //here starts "main" program
{
ActivateItem(new UserInfoViewModel());
}
//and so on...
}

}

我的LoginViewModel.cs:

namespace TaskManager.ViewModels
{
class LoginViewModel : Screen
{
public string Login    { get; set; }
public string Password { get; set; }
public LoginViewModel(FakeData context)
{
this.context = context;
}
public void LoginButton()
{
bool check = Services.Login.IsValid(Login, Password, context);
if(check) //if login is OK, check == true
TryClose();
}
private FakeData context { get; set; } //data is here
}
}

然后,我的IsValid()方法:

namespace TaskManager.Services
{
static class Login
{
static public bool IsValid(string login, string password, FakeData context) 
=> context.users.Any(i => i.Login == login);
//i know it is bad, but its only example
}
}

按钮,打开和关闭窗口非常有效(也可以从文本框中阅读(。我只想得到信息(也许通过参考?(若用户是通过良好的数据。

谢谢你的建议!

您可以为此目的使用EventAggregator。

"事件聚合器是一种提供发布功能的服务以松散的方式从一个实体到另一个实体的对象。">

第一步是在ViewModels中创建EventAggregator的实例并订阅它。您可以在两个ViewModels的构造函数中通过DI来完成。

对于LoginViewModel,

private IEventAggregator _eventAggregator;
public LoginViewModel(FakeData context,IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}

和MainWindowViewModel,

private IEventAggregator _eventAggregator;
public MainWindowViewModel (IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.Subscribe(this);
}

下一步是创建一个消息对象,它可以在ViewModels之间传输所需的信息。

public class OnLoginAttemptMessage
{
string UserName { get; set; }
bool IsLoginSuccessful { get; set; }
}

最后,是时候把所有东西放在一起了。在LoginViewModel中的LoginButton方法中,我们修改代码以在成功登录时引发事件。

public void LoginButton()
{
bool check = Services.Login.IsValid(Login, Password, context);
if(check) //if login is OK, check == true
{
_eventAggregator.PublishOnUIThread(new OnLoginAttemptMessage
{
UserName = Login,
IsLoginSuccessful = check;
});
TryClose();
}
}

最后一步是在MainWindowViewModel中,您需要在其中实现IHandle接口。

class MainWindowViewModel : Conductor<IScreen>.Collection.OneActive, IHandle<OnLoginSuccessMessage>
{
public void Handle(OnLoginSuccessMessage message)
{
if(message.IsLoginSuccessful)
{
// Login is successfull, do next steps.
}
} 
}

您可以在此处阅读EventAggregator上的更多信息(https://caliburnmicro.com/documentation/event-aggregator)

最新更新