In this post we will check a simple example on how can we pass a Model object on a button click in Xamarin Forms with MVVM structure. In the last Xamarin forms tutorial we saw how to check Latitude and Longitude values in Xamarin forms. Here let’s learn about button click events in MVVM architecture. You can download the source code at the end of this post.
Create folders
In your Xamarin project first create 3 folders:
- Models
- ViewModels
- Views
You can also create the respective layout files and classes as shown in the image above. These are just naming standards, you can name the folders with a different name too. Actually this is a first post on this, in the next post I will also explain how to call WebAPIs and create a login app in Xamarin forms.
Creating Model class
Create a new class inside Models folder as below.
Users.cs:
namespace App1.Models { public class Users { public string username { get; set; } public string password { get; set; } } public class UserDetails { public string username { get; set; } public string firstname { get; set; } public string lastname { get; set; } public string dob { get; set; } public string email { get; set; } public string role { get; set; } public string contactno { get; set; } public string gender { get; set; } public Result result { get; set; } } public class Result { public bool result { get; set; } public string message { get; set; } } }
We will pass this model class object between Views and ViewModels.
Creating ViewModels
Here we will create 3 classes:
BaseViewModel.cs:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; namespace XamSamples.ViewModels { public class BaseViewModel : INotifyPropertyChanged { public virtual void OnAppearing() { } protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName] string propertyName = "", Action onChanged = null) { if (EqualityComparer<T>.Default.Equals(backingStore, value)) return false; backingStore = value; onChanged?.Invoke(); OnPropertyChanged(propertyName); return true; } #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = "") { var changed = PropertyChanged; if (changed == null) return; changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion } }
This will be our base class for ViewModels.
VMDashboard.cs:
using App1.Models; using App1.Views; using System; using System.Threading.Tasks; namespace App1.ViewModels { public class VMDashboard : BaseViewModel { private Users _users { get; set; } public Users users { get { return _users; } set { _users = value; OnPropertyChanged(); } } public VMDashboard(Users user) { users = new Users(); users.username = user.username; } } }
This will be called once the user as successfully logged-in. For this tutorial we will only checkout how to pass the model class and call button click event in Xamarin forms MVVM. The logic implementation for actual login process will be made in the next post.
VMLogin.cs:
using App1.Models; using App1.Views; using System; using System.Threading.Tasks; using System.Windows.Input; using Xamarin.Forms; namespace App1.ViewModels { public class VMLogin : BaseViewModel { public ICommand btnLogin { get; set; } private Users _users { get; set; } public Users users { get { return _users; } set { _users = value; OnPropertyChanged(); } } public VMLogin() { users = new Users(); btnLogin = new Command(async () => await userLogin()); } private async Task userLogin() { try { //validation to be done //APIs to be called Application.Current.MainPage = new NavigationPage(new Dashboard(users)); } catch (Exception ex) { } } } }
This is our first page for this app. This ViewModel
class will be called for the login page. Here the btnLogin
command will be used to bind the button on the main view. We are also changing the MainPage
of our application here to Dashboard once the user presses on the button from Login
view.
Creating Views
Create Login.xaml file inside Views folder and edit it as below:
Login.xaml:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="App1.Login" Title="User Login"> <ContentPage.Content> <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Padding="20" Orientation="Vertical"> <Label Text="User Id:" Margin="5"/> <Entry x:Name="txtUserId" HorizontalOptions="FillAndExpand" Margin="5" Text="{Binding users.username, Mode=TwoWay}"/> <Label Text="Password:" Margin="5"/> <Entry x:Name="txtPassword" IsPassword="True" HorizontalOptions="FillAndExpand" Margin="5" Text="{Binding users.password, Mode=TwoWay}"/> <Button x:Name="btnLogin" Text="Login" Command="{Binding btnLogin}"/> </StackLayout> </ContentPage.Content> </ContentPage>
Login.xaml.cs:
using App1.ViewModels; using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace App1 { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class Login : ContentPage { VMLogin vmLogin; public Login() { InitializeComponent(); vmLogin=new VMLogin(); BindingContext = vmLogin; } } }
Dashboard.xaml:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="App1.Views.Dashboard" Title="Dashboard"> <ContentPage.Content> <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Orientation="Vertical" Padding="5"> <Label x:Name="lblName" Text="{Binding users.username}" FontAttributes="Bold" FontSize="25"/> </StackLayout> </ContentPage.Content> </ContentPage>
Dashboard.xaml.cs:
using App1.Models; using App1.ViewModels; using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace App1.Views { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class Dashboard : ContentPage { VMDashboard vmDashboard; public Dashboard(Users users) { InitializeComponent(); vmDashboard = new VMDashboard(users); BindingContext = vmDashboard; } } }
In the App.xaml.cs class file change the start page to Login page.
App.xaml.cs:
using Xamarin.Forms; namespace App1 { public partial class App : Application { public App() { InitializeComponent(); MainPage =new NavigationPage(new Login()); } protected override void OnStart() { } protected override void OnSleep() { } protected override void OnResume() { } } }
Now run the app.