4

For the first time I'm restricting the onAppearing() methods in all child pages of tabbed page. I need to call the onAppearing() when I change the tab. For that, I'm using OnCurrentPageChanged() to call the onAppearing() method. When I change the tab, I'm calling the OnCurrentPageChanged() and giving them access to run the onAppearing() functionality. onAppearing() is calling before calling the OnCurrentPageChanged().

TabbedPage code:

public partial class VendorScheduleTabbedPage : Xamarin.Forms.TabbedPage
    {
       public int isCount;
        public VendorScheduleTabbedPage ()
        {
            InitializeComponent ();
            Xamarin.Forms.Application.Current.Properties["dayOnAppear"] = false;
            Xamarin.Forms.Application.Current.Properties["weekOnAppear"] = false;
            Xamarin.Forms.Application.Current.Properties["monthOnAppear"] = false;
            On<Android>().SetBarItemColor(value: Color.FromHex("#6699FF"));
            On<Android>().SetBarSelectedItemColor(value: Color.Orange);
        }
        override protected void OnCurrentPageChanged()
        {
            isCount = 1;
            if (this.CurrentPage.Title == "Week")
            {
                Xamarin.Forms.Application.Current.Properties["weekOnAppear"] = true;

            }
            if (this.CurrentPage.Title == "Month")
            {
                Xamarin.Forms.Application.Current.Properties["monthOnAppear"] = true;
            }
            else
            {
                Xamarin.Forms.Application.Current.Properties["dayOnAppear"] = true;
            }
            base.OnCurrentPageChanged();
        }
    }
}

Week Page code(child page):

public WeekSchedulePage()
        {
            InitializeComponent();
            NavigationPage.SetHasNavigationBar(this, false);
            timeSlot = new List<VendorScheduleTimeSlot>();
            scheduleSlots = new List<VendorScheduleTimeSlot>();
            lstVendorsData = new List<ScheduledCustomersVM>();
            SortedList = new List<ScheduledCustomersVM>();
            scheduledCustomersList = new List<ScheduledCustomersVM>();
            rescheduledCustomersList = new List<RescheduledCustomersVM>();
            ConfirmBtn.IsVisible = true;
            ConfirmBtn.IsEnabled = false;

            vendorDayAndHoursDataVM = new VendorDayAndHoursDataVM();
            lstDaysAndHours = new List<VendorDayAndHoursDataVM>();
            lstQuestionsData = new List<VendorQuestionsDataVM>();
            overlay.IsVisible = false;
            Alert.IsVisible = false;

            presentWeekDay.Text = DateTime.Now.ToString("dddd, dd MMMM yyyy");

            currentDayName = DateTime.Now.DayOfWeek.ToString();
            currentDate = DateTime.Parse(presentWeekDay.Text);

        }

        protected override void OnAppearing()
        {
            var isAppear = Convert.ToBoolean(Application.Current.Properties["weekOnAppear"].ToString());
            if (isAppear == true)
            {
                ConfirmBtn.IsVisible = true;
                ConfirmBtn.IsEnabled = false;

                overlay.IsVisible = false;
                Alert.IsVisible = false;

                Application.Current.Properties["dayOnAppear"] = true;
                Application.Current.Properties["monthOnAppear"] = true;
                ConfirmBtn.IsEnabled = false;
                scheduledCustomersList.Clear();
                rescheduledCustomersList.Clear();

                presentWeekDay.Text = DateTime.Now.ToString("dddd, dd MMMM yyyy");

                currentDayName = DateTime.Now.DayOfWeek.ToString();

                weekwiseTimeslotClick();

                base.OnAppearing();
            }

        }

Here I need to call OnCurrentPageChanged() method first instead of the OnApearing() method. And OnCurrentPageChanged() will give the bool value to perform the code which is in OnApearing() method.

Yousha Aleayoub
  • 4,532
  • 4
  • 53
  • 64
Moses Burla
  • 53
  • 1
  • 5
  • Why not give the bool to the init of the second page from the first page action? Why do you need to pass it via the Page.Methods? – klingu Dec 19 '19 at 12:39
  • It's a tabbed page...By defaultly i'm displaying some alerts in 3 tabbed pages.those all alerts are displaying at a time in current child page of a tabbed page.for that i restricted my onAppearing() methods in all child pages...Now I'm unable to change the bool values to the session to perform onAppearing() methods when click on particular tab. – Moses Burla Dec 19 '19 at 12:45
  • Are you seeing this issue only on Android, or for both? If only on android, it’s probably because the android platform loads the next tab automatically, in order to display the tab quickly when it’s tapped – Saamer Dec 19 '19 at 13:44
  • Why not create a method in the week (or other) page that you can call from the `OnCurrentPageChanged()` method? Just make sure the page is not null, and if not call that method to to the things you need to do to the page. If the page is null, you can instantiate it and then call the method. However if OnCurrentPageChanged is called after the page appears, then it should not be null. – jgoldberger - MSFT Dec 19 '19 at 21:29

2 Answers2

0

In Android, onAppearing is called before OnCurrentPageChanged while in iOS OnCurrentPageChanged is called before onAppearing.

1.As jgoldberger suggested, you can call method in each Page after CurrentPageChanged:

    override protected void OnCurrentPageChanged()
    {
        if (this.CurrentPage.Title == "Week")
        {
            Xamarin.Forms.Application.Current.Properties["weekOnAppear"] = true;

            NavigationPage naviPage = this.Children[0] as NavigationPage;
            WeekPage page = naviPage.RootPage as WeekPage;
            page.test();

        }else if (this.CurrentPage.Title == "Month")
        {
            Xamarin.Forms.Application.Current.Properties["monthOnAppear"] = true;

            NavigationPage naviPage = this.Children[1] as NavigationPage;
            MonthPage page = naviPage.RootPage as MonthPage;
            page.test();
        }
        else
        {
            Xamarin.Forms.Application.Current.Properties["dayOnAppear"] = true;

            NavigationPage naviPage = this.Children[2] as NavigationPage;
            DayPage page = naviPage.RootPage as DayPage;
            page.test();
        }

        base.OnCurrentPageChanged();
    }
}

2.You can use messaging-center to notify specific page to perform some actions after CurrentPageChanged:

    override protected void OnCurrentPageChanged()
    {
        string testStr;

        if (this.CurrentPage.Title == "Week")
        {
            testStr = "Week";
        }else if (this.CurrentPage.Title == "Month")
        {
            testStr = "Month";
        }
        else
        {
            testStr = "Day";
        }

        MessagingCenter.Send<object, string>(new object(), "CurrentPageChanged", testStr);

        base.OnCurrentPageChanged();
    }

And in each page:

public partial class MonthPage : ContentPage
{
    public MonthPage()
    {
        InitializeComponent();

        MessagingCenter.Subscribe<object, string>(new object(), "CurrentPageChanged", async (sender, arg) =>
        {
            if (arg == "Month")
            {
                Console.WriteLine(arg);
                //do something
            }
        });
    }

    public void test() {

        Console.WriteLine("test");
        //do something
    }
}

BTW, you should use if...else if...else instead of if...if...else in your control statement.

nevermore
  • 15,432
  • 1
  • 12
  • 30
0

I'm still facing this issue on our migration of Xamarin forms from 4.0 to 5.0. Due to the existing code, it is not easy to go with the solution posted here and I found a better solution is to set a flag with the current page index in your tabbed page by overriding OnPropertyChanged event and looking for CurrentPage property.

protected override void OnPropertyChanged(string propertyName = null)
{
    if (propertyName == nameof(CurrentPage))
    {
        myCurrentTabVariable = Children.IndexOf(CurrentPage);
    }
    base.OnPropertyChanged(propertyName);
}

myCurrentTabVariable is a flag that you could access from any of your tabbed page. You could design that by having as a property in your base tab page or as simple as a global variable.

This ensures that before the OnAppearing method of your tab page is called, the flag is set and check for this flag in other tab's OnAppearing method to stop executing if the current tab is not the same.

Renji
  • 123
  • 8