'Xamarin Forms: Pass Information from Modal to Origin Page

Starting by saying I'm a noob at Xamarin Forms. Any help is highly appreciated. I'm making a calculator. If a more complex equation is needed (in this case compound interest), a modal pops up where you can enter all needed info. Then you hit calculate, the modal closes, and you see the calculator again with the answer. I'm sure other things are wrong with my code as well, but right now I'm trying to figure out how to pass the data from the CompoundInterestModal to the CalculatorPage.

Here's my code.

using System;
using System.Collections.Generic;

using Xamarin.Forms;

namespace MyProj.Views
{
    public partial class CompoundInterestModal : ContentPage
    {
        public static decimal final;
        CalculatorPage main;
        
        public CompoundInterestModal(CalculatorPage m)
        {
            InitializeComponent();
            main = m;

            CalculateCI.Clicked += CalculateCI_Clicked;
            
        }
        async void CalculateCI_Clicked(object sender, EventArgs e)
        {
            //main.function()
            await Navigation.PopModalAsync();
            
        }
        void CalculateCompoundInterest(decimal principal, decimal time, decimal interest, decimal compounded)
        {

            double arg2 = Convert.ToDouble(compounded) * Convert.ToDouble(time);
            double arg1 = (Convert.ToDouble(principal) * (1 + (Convert.ToDouble(interest) / Convert.ToDouble(compounded))));
            double calculation = Math.Pow(arg1,arg2);
            final = Convert.ToDecimal(calculation);
        }
    }
}

and

using System;
using Xamarin.Forms;

namespace MyProj.Views
{
    public partial class CalculatorPage : ContentPage
    {

        public CalculatorPage()
        {
            InitializeComponent();
     
        }
        private decimal firstNumber;
        private decimal secondNumber;
        string operatorName;
        private bool isOperatorClicked;
        private decimal accumulated;
        private bool tipSelected;

        void BtnCommon_Clicked(System.Object sender, System.EventArgs e)
        {
            if (tipSelected)
            {
                tipSelected = false;
                LblResult.Text = "0";
                isOperatorClicked = false;
                firstNumber = 0;
            }
            var button = sender as Button;
            if (LblResult.Text == "0" || isOperatorClicked)
            {
                isOperatorClicked = false;
                LblResult.Text = button.Text;
            } else
            {
                LblResult.Text += button.Text;
            }
            firstNumber = Convert.ToDecimal(LblResult.Text);
        }
        void BtnReset_Clicked(System.Object sender, System.EventArgs e)
        {
            LblResult.Text = "0";
            isOperatorClicked = false;
            firstNumber = 0;
            accumulated = 0;
        }
        async void BtnCompound_Clicked(System.Object sender, System.EventArgs e)
        {
            var compoundVars = new CompoundVar
            {
                Principal = 0m,
                Interest = 0m,
                Compounded = 0m,
                Years = 0m
            };
            CompoundInterestModal modalPage = new CompoundInterestModal(compoundVars);
            await Navigation.PushModalAsync(modalPage);

        }
        void BtnCalculateTip_Clicked(System.Object sender, System.EventArgs e)
        {
            tipSelected = true;
            decimal number = Convert.ToDecimal(LblResult.Text);
            decimal tipPercentage = .2m;
            decimal tip = number * tipPercentage;
            decimal total = number + tip;
            LblResult.Text = number.ToString("0.##") + " + " + tip.ToString("0.##") + "(TIP) = " + total.ToString("0.##");
        }
        private async void BtnPercent_Clicked(System.Object sender, System.EventArgs e)
        {
            try
            {
                string number = LblResult.Text;
                if (number != "0")
                {
                    decimal percentValue = Convert.ToDecimal(number);
                    string result = (percentValue / 100).ToString("0.##");
                    LblResult.Text = result;
                }
            } catch (Exception ex)
            {
                await DisplayAlert("Error", ex.Message, "Ok");
            }
        }

        void BtnEquals_Clicked(System.Object sender, System.EventArgs e)
        {
            try
            {
                decimal secondNumber = Convert.ToDecimal(LblResult.Text);
                string finalResult = Calculate(firstNumber, secondNumber).ToString("0.##");
                LblResult.Text = finalResult;
            } catch (Exception ex)
            {
                DisplayAlert("Error", ex.Message, "Ok");
            }
        }
        void BtnPosNeg_Clicked(System.Object sender, System.EventArgs e)
        {
            firstNumber = firstNumber * -1;
            LblResult.Text = firstNumber.ToString("0.##");
        }
        public void BtnCommonOperation_Clicked(object sender, EventArgs e)
        {
            var button = sender as Button;
            isOperatorClicked = true;
            operatorName = button.Text;
            if (firstNumber == 0)
            {
                firstNumber = Convert.ToDecimal(LblResult.Text);
            } else
            {
                secondNumber = Convert.ToDecimal(LblResult.Text);
            }
            //accumulated = Calculate(firstNumber, secondNumber);
        }
        public decimal Calculate(decimal firstNumber, decimal secondNumber)
        {
            decimal result = 0;
            if (operatorName == "+")
            {
                result = firstNumber + secondNumber;
            }
            else if (operatorName == "-")
            {
                result = firstNumber - secondNumber;
            }
            else if (operatorName == "x")
            {
                result = firstNumber * secondNumber;
            }
            else if (operatorName == "÷")
            {
                result = firstNumber / secondNumber;
            }
            return result;
        }
        public void BtnDelete_Clicked(object sender, EventArgs e)
        {
            string number = LblResult.Text;
            if (number != "0")
            {
                number = number.Remove(number.Length - 1, 1);
                if (string.IsNullOrEmpty(number))
                {
                    LblResult.Text = "0";
                }
                else
                {
                    LblResult.Text = number;
                }
            }
        }

    }
}

and

using System;

using Xamarin.Forms;

namespace MyProj
{
    public class CompoundVar
    {
        public decimal Principal { get; set; }
        public decimal Interest { get; set; }
        public decimal Compounded { get; set; }
        public decimal Years { get; set; }
    }
}



Solution 1:[1]

You can do that by custom events. In CompoundInterestModal:

 public event EventHandler<CompoundVar> Item;

protected virtual void SendItem (CompoundVar e)
    {
        EventHandler<CompoundVar> handler = Item;
        if (handler != null)
        {
            handler(this, e);
        }
    }

async void CalculateCI_Clicked(object sender, EventArgs e)
        {
           SendItem(new CompoundVar {...} );
            await Navigation.PopModalAsync();
            
        }

In CalculatorPage , before navigating to the next page subscribe to the event:

async void BtnCompound_Clicked(System.Object sender, System.EventArgs e)
        {
            var compoundVars = new CompoundVar
            {
                Principal = 0m,
                Interest = 0m,
                Compounded = 0m,
                Years = 0m
            };
            CompoundInterestModal modalPage = new 
          CompoundInterestModal(compoundVars);
           modalPage.SendItem += Details_ItemSent;
            await Navigation.PushModalAsync(modalPage);

        }

private void Details_ItemSent(object sender, CompoundVar e)
{
    Console.WriteLine("The Principal : " + e.Principal);
}

Inherit : EventArgs to your model:

public class CompoundVar : EventArgs
    {
        public decimal Principal { get; set; }
        public decimal Interest { get; set; }
        public decimal Compounded { get; set; }
        public decimal Years { get; set; }
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Amjad S.