Better way to do data binding

theocangtheocang Member ✭✭✭

I have a login page where when the user click on login button call a command in the view model

#region Command
        private Command clickLogin;
        public ICommand ClickLogin
        {
            get
            {
                return clickLogin ?? (clickLogin = new Command(async () => await CheckUserLoginAsync()));
            }
        }
        #endregion


        private async Task CheckUserLoginAsync()
        {
            await Task.Run(() =>
            {
                var isValid = AreCredentialsCorrect(this.User);
                if (isValid)
                {
                    this.IsValidConnexion = true;
                }
                else
                {
                    this.IsValidConnexion = false;
                }
            });

        }

        private bool AreCredentialsCorrect(LoginModel user)
        {
            return user.Username == Username && user.Password == Password;
        }

After that I am lost I would if the IsValidConnexion=true go on a new page but I can can only do this in code-behind.
How I can do this?

Thanks

Answers

  • chetanrawatchetanrawat USMember ✭✭✭

    Hi @theocang

    Put your page on navigation page.

    var nav = ((App.Current.MainPage as RootPage) as NavigationPage).Navigation;
    await nav.PushAsync(new Pages.Spotlight.MapPage(args));

    where Rootpage is your MainPage

  • theocangtheocang Member ✭✭✭

    @chetanrawat
    Hello thanks for the answer but I can you be more specific I don't understand very well what you would like do.

  • LandLuLandLu Member, Xamarin Team Xamurai

    What do you mean

    After that I am lost I would if the IsValidConnexion=true go on a new page but I can only do this in code-behind.
    How I can do this?

    If you are saying you want to navigate to a new page in the View Model just as what you can do in the page's cs file. You can try to pass the navigation to the View Model, then consume it there. The View Model's constructor could be like this:

    public class MainPageViewModel
    {
        INavigation _navigation;
        public MainPageViewModel(INavigation navigation)
        {
            _navigation = navigation;
        }
    
        private Command clickLogin;
        public ICommand ClickLogin
        {
            get
            {
                return clickLogin ?? (clickLogin = new Command(async () => await CheckUserLoginAsync()));
            }
        }
    
        private async Task CheckUserLoginAsync()
        {
            await Task.Run(() =>
            {
                var isValid = AreCredentialsCorrect(this.User);
                if (isValid)
                {
                    this.IsValidConnexion = true;
    
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        _navigation.PushAsync(new SignInPage());
                    });
                }
                else
                {
                    this.IsValidConnexion = false;
                }
            });    
        }        
    }
    

    Set the Binding Context in the content page:

    BindingContext = new MainPageViewModel(Navigation);

  • theocangtheocang Member ✭✭✭

    @LandLu Thanks for the answer but no I don't want pass navigation in ViewModel it's break MVVM, so I have do this to respect MVVM.

    private async void LoginBtn_Clicked(object sender, System.EventArgs e)
            {
                var connexion = this.loginViewModel.CheckUserLoginAsync();
                if (connexion)
                {
                    try
                    {
                        MenuView view = new MenuView();
                        Application.Current.MainPage = view;
                        await this.Navigation.PopAsync();
                    }
                    catch (Exception ex)
                    {
                        await DisplayAlert("Error", ex.Message, "OK");
                    }
                }
            }
    
  • LandLuLandLu Member, Xamarin Team Xamurai

    @theocang You can use this way to pop to the previous page. But why do you think that passing the INavigation to view model will break the MVVM?
    I think you will get the main page in your view model in the way you post above. This behavior is what you mentioned about break MVVM.

  • theocangtheocang Member ✭✭✭

    @LandLu

    Because pass Navigation into ViewModels link UI with Business logic. And the purpose on ViewModel is to separate them.
    So that not the good way to passe Navigation into viewModel

  • LandLuLandLu Member, Xamarin Team Xamurai
    edited February 21

    @theocang We just pass some parameters at the binding time. After doing this, the view model and the page are totally independent. If we don't do this configuration, how can you bind your view model to your page?
    But when you retrieve the page in your view model, I don't think you have separated them.
    Moreover, INavigation is not UI related.

  • theocangtheocang Member ✭✭✭

    @LandLu Ok, go see this on the forum and telle me what did you think?

    Question : Navigation in ViewModel with MVVM.

Sign In or Register to comment.