简体   繁体   中英

Get info from another window in Caliburn.Micro, WPF, MVVM

Im making Login Window in my app based on Caliburn.Micro mvvm framework. So, how to return an property (for example, true if user passed good data or false , if he pass bad credentials) from TryClose() method from my Login Window that is initialize by Caliburn.Micro? How to get information from window opened in IWindowManager.ShowDialog() ?

First, my 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...
    }

}

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

Then, my IsValid() Method:

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

Buttons, opening and closing windows works great (reading from textboxes too). I want only get info (maybe by reference?) if user is pass good data.

THanks for your advices!

You can make use of EventAggregator for the purpose.

"An Event Aggregator is a service that provides the ability to publish an object from one entity to another in a loosely based fashion. "

The first step would be create instance of EventAggregator in your ViewModels and subscribe to it. You can do it via DI in constructor of both ViewModels.

For LoginViewModel,

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

And MainWindowViewModel,

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

The next step is to create a Message Object, which can transmit the required information between the ViewModels.

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

Finally, it is time to put everything together. In youg LoginButton method in LoginViewModel, we modify the code to raise the event on successfull login.

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();
   }
 }

The last step is in MainWindowViewModel, where you need to implement the IHandle interface.

class MainWindowViewModel : Conductor<IScreen>.Collection.OneActive, IHandle<OnLoginSuccessMessage>
{

        public void Handle(OnLoginSuccessMessage message)
        {
            if(message.IsLoginSuccessful)
            {
                // Login is successfull, do next steps.
            }
        } 
}

You can read more on EventAggregator here ( https://caliburnmicro.com/documentation/event-aggregator )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM