Xamarin Entry Binding to MVVM

Issue

I am trying to implement everything I can with MVVM rather than code behind, but if I have many objects that I need to access when the entry changes, I don’t know how to do it well if at all.

Xaml:

<Entry x:Name"UpdatedCost"                       
       TextChanged"UpdatedCost_TextChanged"/>

<Label x:Name"PriceDifLabel"/>

<Entry x:Name"CurrentCost"
       Text"2.5"/>

<Entry x:Name"CurPriceUpdatedCostProfit"
        Text"22%"/>

Code-Behind:

private void UpdatedCost_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (double.TryParse(e.NewTextValue, out double UpdatedCost))
            {
                double diff  UpdatedCost - double.Parse(CurrentCost.Text);
                string sign  diff > 0 ? "+" : "";
                PriceDifLabel.Text  "(" + sign + string.Format("{0:0.0}", diff) +")";
                PriceDifLabel.TextColor  diff > 0 ? Color.Red : Color.Green;
                PriceDifLabel.BackgroundColor  Color.Yellow;
                CurPriceUpdatedCostProfit.Text  ((int)((double.Parse(CurrentPrice.Text) - UpdatedCost) /
                                                   double.Parse(CurrentPrice.Text) * 100)).ToString() + "%";
            }


        }

I would highly appreciate as detailed help as possible converting this method to MVVM implementation. If it is relevant, my view model is implementing BaseViewModel of MvvmHelpers.

Thank you very much!

Solution

Yes, you can create a model and create different properties for different controls. I created a simple demo based on your code(take the PriceDifLabel ‘s text and text color for example).

You can refer to the following code:

1.create a model MyViewModel.cs and implement interface INotifyPropertyChanged.

And when we change the value of UpdatedCost(bind for Entry UpdatedCost),we can also change the PriceDif accordingly.

MyViewModel.cs

   public class MyViewModel: INotifyPropertyChanged
    {
        double _updatedCost;
        public double UpdatedCost
        {
            set { 
                SetProperty(ref _updatedCost, value);
                double diff  UpdatedCost - double.Parse(CurrentCost);
                string sign  diff > 0 ? "+" : "";

                PriceDif  "(" + sign + string.Format("{0:0.0}", diff) + ")";

                PriceDifLabelColor  diff > 0 ? Color.Red : Color.Green;

                System.Diagnostics.Debug.WriteLine("----------> PriceDif  " + PriceDif);
            }

            get { return _updatedCost; }
        }

        string _currentCost;
        public string CurrentCost
        {
            set { SetProperty(ref _currentCost, value); }

            get { return _currentCost; }
        }


        string _priceDif;
        public string PriceDif
        {
            set { SetProperty(ref _priceDif, value); }

            get { return _priceDif; }
        }

        Color _priceDifLabelColor  Color.Green;
        public Color PriceDifLabelColor
        {
            set { SetProperty(ref _priceDifLabelColor, value); }

            get { return _priceDifLabelColor; }
        }

        public MyViewModel() {
            CurrentCost  "2.5";
        }   

        bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName  null)
        {
            if (Object.Equals(storage, value))
                return false;

            storage  value;
            OnPropertyChanged(propertyName);
            return true;
        }

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

        public event PropertyChangedEventHandler PropertyChanged;
    }

2.bind these properties in page.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" xmlns:testapp1"clr-namespace:TestApp1"
             x:Class"TestApp1.TestPage2">

    <ContentPage.BindingContext>
        <testapp1:MyViewModel></testapp1:MyViewModel>
    </ContentPage.BindingContext>
    <ContentPage.Content>
        <StackLayout>
            <Entry x:Name"UpdatedCost" Text"{Binding UpdatedCost}" />

            <Label x:Name"PriceDifLabel" Text"{ Binding PriceDif}" TextColor"{Binding PriceDifLabelColor}"/>

            <Entry x:Name"CurrentCost" Text"2.5"/>

            <Entry x:Name"CurPriceUpdatedCostProfit" Text"22%"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

For more about INotifyPropertyChanged Interface, you can check:

https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/binding-mode#viewmodels-and-property-change-notifications .

Answered By – Jessie Zhang -MSFT

Leave a Comment