How do I do a Login from one Window to another Window in order for me to get the user's details after the login?
I know that "a ViewModel shouldn't know anything about the View", but I really haven't found an "MVVM way" to do this.
I Login my User like this:
LoginViewModel:
class LoginWindowViewModel : BaseViewModel
{
private readonly UserAccountRepository _userAccountRepository;
public event EventHandler Closed; //The Window (LoginWindow) closes itself when this event is executed
public LoginWindowViewModel() //constructor
{
_userAccountRepository = new UserAccountRepository();
CurrentUserAccount = new UserAccount();
LoginCommand = new DelegateCommand(Login);
}
public UserAccount CurrentUserAccount { get; set; }
public ICommand LoginCommand { get; }
private void Login()
{
if (TextboxAndPasswordboxIsNotBlank())
{
UserAccount userToLogin = _userAccountRepository.Get(CurrentUserAccount.Username); //CurrentUserAccount.Username is binded to a Textbox in the UI
//This is a view (and it is now involved in the ViewModel)
MainWindow mainWindow = new(userToLogin); //I passed my user details to the MainWindow here
//this shows my MainWindow
mainWindow.Show();
//and closes the LoginWindow
Close();
}
}
//The method that executes Closed EventHandler
private void Close()
{
Closed?.Invoke(this, EventArgs.Empty);
}
}
I set the DataContext of my MainWindow at the code-behind:
public partial class MainWindow : Window
{
/*
If I set the DataContext at the xaml (Window level) like this:
d:DataContext="{d:DesignInstance Type=windows:MainWindowViewModel}"
I will not be able to get the current logged in user, that's why I set the DataContext here at the code-behind
*/
readonly MainWindowViewModel _viewModel;
//I pass the UserAccount here so that the MainWindow's ViewModel can USE the LOGGED IN User's details
public MainWindow(UserAccount currentUserAccount)
{
InitializeComponent();
_viewModel = new MainWindowViewModel(currentUserAccount);
DataContext = _viewModel;
}
}
This is the MainWindow's ViewModel (MainWindowViewModel):
public class MainWindowViewModel : BaseViewModel
{
private readonly UserAccountRepository _userAccountRepository;
public ICommand UpdateCurrentUserCommand { get; } //used in UserAccountView
public ICommand DeleteCurrentUserCommand { get; } //used in UserAccountView
public ICommand DashboardViewCommand { get; }
public ICommand ProfileViewCommand { get; }
public DashboardViewModel DashboardVM { get; set; }
public UserAccountViewModel ProfileVM { get; set; }
public object CurrentView { get; set; }
public UserAccount CurrentUserAccount { get; set; }
public MainWindowViewModel(UserAccount currentUserAccount) //now I can get the current logged in UserAccount through this
{
CurrentUserAccount = currentUserAccount;
_userAccountRepository = new UserAccountRepository();
UpdateCurrentUserCommand = new DelegateCommand(Update);
DeleteCurrentUserCommand = new DelegateCommand(Delete);
DashboardVM = new DashboardViewModel();
ProfileVM = new UserAccountViewModel();
CurrentView = DashboardVM; //This is managed by a ContentControl in the MainWindow
//This is for navigating through different views
DashboardViewCommand = new NavigationCommand(o => { CurrentView = DashboardVM; });
ProfileViewCommand = new NavigationCommand(o => { CurrentView = ProfileVM; });
Get();
}
public void Get()
{
UserAccount userAccount = _userAccountRepository.Get(CurrentUserAccount.Username);
//Some Logic
}
public void Update()
{
bool idExists = _userAccountRepository.IdExistsInDatabase(CurrentUserAccount.Id);
//Some Logic
}
private void UpdateCurrentUser()
{
bool isUpdate = _userAccountRepository.Update(CurrentUserAccount);
//Some Logic
}
public void Delete()
{
bool isDeleted = _userAccountRepository.Delete(CurrentUserAccount.Id);
//Some Logic
}
}
A problem arises because of this login system. I can't use the MainWindowViewModel as a DataContext for the MainWindow and the UserAccountView. I asked a question here, and I think that making my "Login system" like this causes this problem. (It turns out that I need a shared ViewModel to solve my problem (My ultimate goal here is to update the sidebar username, if the username gets updated in the UserAccountView)