Tag Archive : MVVM

/ MVVM

The MVVM and Fody

The MVVM (Model, View, ViewModel) pattern helps you to organise and structure your code to create better apps.With this pattern you can split your code in 3 main parts:Model: Where you put your dataViewModel: It’s the logic of your app and a link between the Model and the ViewView: It’s the UI of your app (usually written in XAML) The main idea is to keep model, logic and UI completely separated.  And let’s be honest, this is how you should write your app.The interaction between the View and the ViewModel is done with the Data Binding

The Data Binding

The Data Binding is the connection between the UI and ViewModel of your app.You use it to connect a control (eg. a text) of your UI to your logic.Let’s say that we have an Entry (where a user can insert a text) and we want to link it to our ViewModel.We have something like this:in our UI (the View):

<Entry Text="{Binding Username}" Placeholder="Your username" />

In our ViewModel:

//OUR PROPERTY
        private string _username;

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

In this case we have linked the Entry in our UI with the property (Username) in our ViewModel. When the user writes something in this entry, the Username value will change accordingly. And because the link is bidirectional (by default but you can change this behaviour), if we change the property value (eg. loading it from a database) the UI will change accordingly. It’s amazing. Isn’t it?

How to improve the code

To make a link between the UI and the ViewModel we need to use properties. Inside the set of each property we must call OnPropertyChanged (so our ViewModel must implement the INotifyPropertyChanged interface).It works, that’s great, but in a View usually we have a lot of interactive controls and for each of these we should need a property so there are cases where in our ViewModel we have many properties and you can imagine that the code is not readable anymore.Can we improve this? YES!

FODY

Fody is a library for IL weaving (the process to manipulate/inject code in IL). To put it easy, Fody will update automatically our code for us adding new cool features. In this case we are interested in a particular nuget plugin for Fody called PropertyChanged. This plugin will “Inject code which raises the PropertyChanged event, into property setters of classes which implement INotifyPropertyChanged.”What it means, is that we don’t have to explicitly call OnPropertyChanged() but we can instead use Auto-Properties.We can therefore convert our previous Username property to this:

public string Username { get; set; }

We have reduced the number of lines of code from 10 to 1. IMPRESSIVE!. Let’s say that in our ViewModel we have 20 properties, we have 200 lines of code only to declare our properties. With Fody & PropertyChanged plugin we can have only 20 lines of code instead of 200, saving 180 lines! Not Bad!

How to add it to your project

The process in incredibly easy:

  1. In your project install the Fody plugin (only in your PCL/.Net Standard project, in case of Xamarin, you don’t need to install in the Android, iOS,UWP projects): Fody
  2. Install the PropertyChanged plugin (only in your PCL/.Net Standard project): PropertyChanged
  3. Add to your PCL/.NetStandard project a new file called FodyWeavers.xml
  4. Open the file and change its content to:
<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
    <PropertyChanged/>
</Weavers>

IMPORTANT: PropertyChanged will convert your properties only inside the viewmodels that implement the INotifyPropertyChanged interface. So don’t forget to do it in your ViewModels where you want to use Fody PropertyChanged:

public class LoginViewModel : INotifyPropertyChanged

How to add a Checkbox in Xamarin.Forms

May 14, 2019 | Tutorial | No Comments

We are going to show step by step how to create a Checkbox for Xamarin.Forms with a very simple code without the use of Custom Renderers.This checkbox will work on every platform: Android, iOS, UWP… and the final result will be something like:

Checkbox disabled
Checkbox disabled
Checkbox enabled
Checkbox enabled

There are just two steps you need to do:

  • Add your images
  • Create the Checkbox class

After the two steps, I’m going to show you a small example on how to use this checkbox.

Add the Checkbox images

The first thing to do is to choose two images for the checkbox, one enabled and the other disabled (similat to the ones you can see in the previous images).

Add the images as embedded resources
Add the images as embedded resources

Create an Images folder inside your PCL/.NetStandard project and add the two images in it. Be sure to set the two images as Embedded Resources (as in the previous image).

Add the Checkbox class

Now it’s time to create our checkbox class. Inside your PCL/.NetStandard project create the file Checkbox:

using System;
using System.Windows.Input;
using Xamarin.Forms;

namespace Tutorial02
{
    public class Checkbox : StackLayout
    {
        public event EventHandler CheckedChanged;
        private readonly Image _image;

        private readonly Label _label;
        //CHANGE THESE 2 STRINGS ACCORDING TO YOUR NAMESPACE AND IMAGE

        static string imgUnchecked = "Tutorial02.Images.unchecked.png";
        static string imgChecked = "Tutorial02.Images.checked.png";
        public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(Checkbox));

        public static readonly BindableProperty CheckedProperty = BindableProperty.Create("Checked", typeof(Boolean?), typeof(Checkbox), null,
            BindingMode.TwoWay, propertyChanged: CheckedValueChanged);

        public static readonly BindableProperty TextProperty =
            BindableProperty.Create("Text", typeof(String), typeof(Checkbox), null, BindingMode.TwoWay, propertyChanged: TextValueChanged);

        public ICommand Command
        {
            get => (ICommand) GetValue(CommandProperty);
            set => SetValue(CommandProperty, value);
        }

        public Boolean? Checked
        {
            get => (bool?) GetValue(CheckedProperty);
            set => SetValue(CheckedProperty, value);
        }

        public String Text
        {
            get => (string) GetValue(TextProperty);
            set => SetValue(TextProperty, value);
        }

        public Checkbox()
        {
            Orientation = StackOrientation.Horizontal;
            BackgroundColor = Color.Transparent;
            _image = new Image()
                {Source = ImageSource.FromResource(imgUnchecked), HeightRequest = 35, WidthRequest = 35, VerticalOptions = LayoutOptions.Center};
            var tg = new TapGestureRecognizer();
            tg.Tapped += Tg_Tapped;
            _image.GestureRecognizers.Add(tg);
            Children.Add(_image);
            _label = new Label() {VerticalOptions = LayoutOptions.Center};
            _label.GestureRecognizers.Add(tg);
            Children.Add(_label);
        }

        private void Tg_Tapped(object sender, EventArgs e)
        {
            Checked = !Checked;
        }

        private static void CheckedValueChanged(BindableObject bindable, object oldValue, object newValue)
        {
            if (newValue != null && (Boolean) newValue) ((Checkbox) bindable)._image.Source = ImageSource.FromResource(imgChecked);
            else ((Checkbox) bindable)._image.Source = ImageSource.FromResource(imgUnchecked);
            ((Checkbox) bindable).CheckedChanged?.Invoke(bindable, EventArgs.Empty);
            ((Checkbox) bindable).Command?.Execute(null);
        }

        private static void TextValueChanged(BindableObject bindable, object oldValue, object newValue)
        {
            if (newValue != null) ((Checkbox) bindable)._label.Text = newValue.ToString();
        }
    }
}

Your are now ready to use the checkbox in your apps and it will work for every platform supported by Xamarin. GREAT!Now I’ll show you a small example on how to use this checkbox inside your App:

Add the Checkbox to your ContentPage

Inside the our ContentPage we have set the ViewModel and then added the checkbox:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"             
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"             
             xmlns:local="clr-namespace:Tutorial02"
             xmlns:viewModel="clr-namespace:SafePhoto2.ViewModel;assembly=SafePhoto2"
             x:Class="Tutorial02.MainPage">
    <ContentPage.BindingContext>
        <viewModel:MainViewModel />
    </ContentPage.BindingContext>
    <local:Checkbox VerticalOptions="CenterAndExpand"                     
                    HorizontalOptions="CenterAndExpand"                     
                    Checked="{Binding IsChecked}"                     
                    Text="{Binding TextCheckBox}"                     
                    Command="{Binding OnCheckedChanged}">

    </local:Checkbox>
</ContentPage>

The checkbox has two important properties: Checked and Text.

  • Checked is bound to the IsChecked property of the ViewModel and indicates if the checkbox is checked or not
  • Text is bound to the TextCheckBox property of the ViewModel and is the text that appears next to the CheckBox image

In case you want to execute an action after the status of the checkbox is changed, you can use Command  (bound to the OnCheckedChanged inside the ViewModel) otherwise you can remove it from your XAML.

Create the ViewModel

The ViewModel used in our example is very easy and you can change it as you prefer. For this simple example we have just created a basic ViewModel:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using Xamarin.Forms;

namespace Tutorial02
{
    public class MainViewModel : INotifyPropertyChanged
    {
        private bool _isChecked;
        private string _textCheckBox;
        public event PropertyChangedEventHandler PropertyChanged;

        public bool IsChecked
        {
            get => _isChecked;
            set
            {
                _isChecked = value;
                TextCheckBox = _isChecked ? "Is Enabled" : "Is Disabled";
                OnPropertyChanged();
            }
        }

        public string TextCheckBox
        {
            get => _textCheckBox;
            set
            {
                _textCheckBox = value;
                OnPropertyChanged();
            }
        }

        public Command OnCheckedChanged { get; set; }

        public MainViewModel()
        {
            OnCheckedChanged = new Command(OnCheckBoxChanged);
        }

        private void OnCheckBoxChanged()
        {
        }

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

As usual the ViewModel inherits from INotifyPropertyChanged.We have added two properties IsChecked and TextCheckBox and the Command OnCheckedChanged required only if we want to execute an action after the status of the checkbox is changed.When the IsChecked value changes, we set the Checkbox text to Is Enabled or Is Disabled according to its value.

Conclusion

In this tutorial we have seen how to create a Checkbox in Xamarin.Forms.The code is incredibly easy and ready to be used (you can copy and paste the code and it will work).If you have questions or doubts leave here a comment.If you need more info about the MVVM pattern in Xamarin you can check the Microsoft documentation here: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm