MVVM - How to call a function on button click?

So, I'm a little confused about how the MVVM architecture can help me and how to use it in this situation:

I am using Xamarin and am creating my own view and view controller in iOS as an example. I also implemented the MVVMLight toolkit, and created my ViewModel for the view controller and view controller.

I am creating a login screen so the user enters their username and password and they are updated in the model via RaisePropertyChanged () events. My question is where do I need to call the function to validate this information and actually log in?

I've implemented a RelayCommand that will call a method in the ViewModel whenever a button is clicked as I've seen in other tutorials and so on, but I'm not sure what I should call the validation code here.

Some examples of what I have:

LoginViewModel.cs:

public class LoginViewModel : ViewModelBase
{
    private string _username;
    private string _password;

    public RelayCommand LoginButtonCommand { get; private set; }
    public bool CanExecuteLoginCommand { get; set; }

    public LoginViewModel()
    {
        LoginButtonCommand = new RelayCommand(HandleLoginButtonCommand, () => CanExecuteLoginCommand);
        CanExecuteLoginCommand = true;
    }

    public string Username
    {
        get
        {
            return _username;
        }
        set
        {
            _username = value;
            RaisePropertyChanged(() => Username);
        }
    }

    public string Password
    {
        get
        {
            return _password;
        }
        set
        {
            _password = value;
            RaisePropertyChanged(() => Password);
        }
    }

    private void HandleLoginButtonCommand()
    {
        CanExecuteLoginCommand = false;

        //Validate login?

        CanExecuteLoginCommand = true;
    }
}

      

LoginViewController.cs:

public partial class LoginViewController : UIViewController
{
    private Binding _usernameTextFieldBinding;
    private Binding _passwordTextFieldBinding;
    private LoginViewModel _viewModel;

    public LoginViewController(IntPtr handle) : base(handle)
    {           
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
        _viewModel = Application.Locator.Login;

        HideKeyboardHandling(UsernameTextField);
        HideKeyboardHandling(PasswordTextField);

        _usernameTextFieldBinding = this.SetBinding(
            () => _viewModel.Username)
            .ObserveSourceEvent("EditingDidEnd")
            .WhenSourceChanges(() => _viewModel.Username = UsernameTextField.Text);
        _passwordTextFieldBinding = this.SetBinding(
            () => _viewModel.Username)
            .ObserveSourceEvent("EditingDidEnd")
            .WhenSourceChanges(() => _viewModel.Password = PasswordTextField.Text);

        Loginbutton.SetCommand("TouchUpInside", _viewModel.LoginButtonCommand);
    }

    public override void DidReceiveMemoryWarning()
    {
        base.DidReceiveMemoryWarning();
        // Release any cached data, images, etc that aren't in use.     
    }

    void HideKeyboardHandling(UITextField textField)
    {
        textField.ShouldReturn = TextField =>
        {
            TextField.ResignFirstResponder();
            return true;
        };

        var gesture = new UITapGestureRecognizer(() => View.EndEditing(true));
        gesture.CancelsTouchesInView = false;
        View.AddGestureRecognizer(gesture);
    }
}

      

+3


source to share


1 answer


It all depends on how strict you want to be with the Single Responsibility Principle (SPR). This, in turn, depends on how complex your application is. The more complex the application, the more segregated the responsibilities.

A typical MVVM implementation handles commands in the ViewModel. And the ViewModel redirects the call to the Model. But it still puts two responsibilities (like presentation and command management) into one component, aka ViewModel.



A stricter approach would be to have the ViewModel only handle the view logic. Create a separate controller to house all command handlers. And the command handlers redirect the calls to the Model.

A more relaxed approach would be to simply implement the business logic in the ViewModel. This means you don't have a business logic layer. Which is good if your application is simple enough that the business logic layer is not worth the effort.

+3


source







All Articles