从 Caliburn.Micro、WPF、MVVM 中的另一个 window 获取信息
Get info from another window in Caliburn.Micro, WPF, MVVM
我正在基于 Caliburn.Micro mvvm 框架在我的应用程序中进行登录 Window。那么,如何从 TryClose()
方法中 return 一个 属性 (例如,如果用户传递了正确的数据,则 true
或如果他传递了错误的凭据,则 false
)我的登录 Window 是由 Caliburn.Micro 初始化的?如何从 IWindowManager.ShowDialog()
中打开的 window 获取信息?
首先,我的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
}
}
按钮,打开和关闭 windows 效果很好(也可以从文本框中读取)。如果用户传递了良好的数据,我只想获取信息(也许通过参考?)。
感谢您的建议!
您可以为此目的使用 EventAggregator。
"An Event Aggregator is a service that provides the ability to publish
an object from one entity to another in a loosely based fashion. "
第一步是在您的 ViewModel 中创建 EventAggregator 实例并订阅它。您可以在两个 ViewModel 的构造函数中通过 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);
}
下一步是创建一个消息对象,它可以在 ViewModel 之间传输所需的信息。
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)
我正在基于 Caliburn.Micro mvvm 框架在我的应用程序中进行登录 Window。那么,如何从 TryClose()
方法中 return 一个 属性 (例如,如果用户传递了正确的数据,则 true
或如果他传递了错误的凭据,则 false
)我的登录 Window 是由 Caliburn.Micro 初始化的?如何从 IWindowManager.ShowDialog()
中打开的 window 获取信息?
首先,我的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
}
}
按钮,打开和关闭 windows 效果很好(也可以从文本框中读取)。如果用户传递了良好的数据,我只想获取信息(也许通过参考?)。
感谢您的建议!
您可以为此目的使用 EventAggregator。
"An Event Aggregator is a service that provides the ability to publish an object from one entity to another in a loosely based fashion. "
第一步是在您的 ViewModel 中创建 EventAggregator 实例并订阅它。您可以在两个 ViewModel 的构造函数中通过 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);
}
下一步是创建一个消息对象,它可以在 ViewModel 之间传输所需的信息。
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)