c# - 从 Caliburn.Micro、WPF、MVVM 中的另一个窗口获取信息
问题描述
我基于 Caliburn.Micro mvvm 框架在我的应用程序中制作登录窗口。那么,如何从由 Caliburn.Micro 初始化的登录窗口中的方法返回一个属性(例如,true
如果用户传递了良好的数据,或者false
,如果他传递了错误的凭据) ?TryClose()
如何从打开的窗口中获取信息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。
“事件聚合器是一种服务,它提供了以松散的方式将对象从一个实体发布到另一个实体的能力。”
第一步是在您的 ViewModel 中创建 EventAggregator 的实例并订阅它。您可以通过两个 ViewModel 的构造函数中的 DI 来实现。
对于登录视图模型,
private IEventAggregator _eventAggregator;
public LoginViewModel(FakeData context,IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}
和 MainWindowViewModel,
private IEventAggregator _eventAggregator;
public MainWindowViewModel (IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.Subscribe(this);
}
下一步是创建一个消息对象,它可以在 ViewModel 之间传输所需的信息。
public class OnLoginAttemptMessage
{
string UserName { get; set; }
bool IsLoginSuccessful { get; set; }
}
最后,是时候把所有东西放在一起了。在 LoginViewModel 的 youg 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 )
推荐阅读
- r - 使用距离包的nearest_neighbor_search
- python - Sublime Text 3 使用 .split() 方法时没有显示输出
- ios - UIKitCore、CoreFoundation 等缺少 dSYM
- python - Numpy - 一维输入数组的多个 numpy.roll
- angular - 如何同时订阅两个 observable,第二个 observable 参数取决于第一个 observable 的结果?
- c# - 强制在 EF Core 下显式设置 ID 时无法添加实体
- angular - Angular Typescript Object.prototype.get()
- python - 当控制台输出重新路由到 GUI 时暂停 Python 代码
- anaconda - 无法使用 python=3.4 创建 Anaconda 环境
- jquery - 为什么DataTable只显示数组的第一行