Label at the bottom right corner of every page.

MikilllMikilll Member ✭✭✭

I need to place a label at the bottom right corner of every page with the information about data last retrieval date. Is it possible to do that without breaking existing views? I was looking for some solution on the Internet but there were rather not satisfying.

Posts

  • JGoldbergerJGoldberger USMember, Forum Administrator, Xamarin Team, University Xamurai

    @Mikilll

    There is a PageAppearing and PageDisappearing event you can subscribe to in your App class. When that event fires, you can get a reference to the page and the layout the page uses and add your Label. e.g.:

     public App()
     {
          ...
          PageAppearing += Handle_PageAppearing;
          PageDisappearing += Handle_PageDisappearing;
     }
    
        void Handle_PageAppearing(object sender, Page e)
        {
            // Here you can test for the type of page it is, and get a reference to the page
            if (e.GetType().BaseType == typeof(ContentPage))
            {
                ContentPage page = e as ContentPage;
    
                var content = page.Content;
    
                // Here you can test for the type of content the page has, i.e. what type of layout, 
                //and get a reference to the layout. 
                if (content.GetType() == typeof(StackLayout))
                {
                    var layout = content as StackLayout;
                    // Now add a child to the layout. (how you do this of course will vary
                    // based on layout type)
                    layout.Children.Add(new Label { Text = lastRetrievalDateString, VerticalOptions = LayoutOptions.End });
                }
    
            }
    
        }
    
        void Handle_PageDisappearing(object sender, Page e)
        {
            // To avoid adding the element again during back navigation, 
            // remove the element you added above (how you do this of course will vary
            // based on layout type)
            if (e.GetType().BaseType == typeof(ContentPage))
            {
                ContentPage page = e as ContentPage;
    
                var content = page.Content;
    
                if (content.GetType() == typeof(StackLayout))
                {
                    var layout = content as StackLayout;
                    layout.Children.Remove(layout.Children.Last());
                }
    
            }
        }
    

    There may be more elegant ways to do this, but hopefully this will get you going.

  • JohnHardmanJohnHardman GBUniversity mod
    edited June 2018

    @Mikilll - Easiest way is probably to subclass ContentPage and have all of your pages use that new subclass.

    What to do in the subclass depends on whether you want the last retrieval date to overlay the existing page content, or whether you want the existing page content to be reduced in height and the last retrieval date put below the existing content.

    In the case of reducing the height of the existing page content:

    • Create a new StackLayout
    • Get the Content of the ContentPage and add it to the StackLayout
    • Add the Label for the last retrieval date to the StackLayout
    • Set the Content of the ContentPage to the StackLayout

    In the case of overlaying the existing page content:

    • Create an AbsoluteLayout (you could alternatively use a RelativeLayout or Grid)
    • Get the Content of the ContentPage and add it to the AbsoluteLayout
    • Add the Label for the last retrieval date to the AbsoluteLayout
    • Set the Content of the ContentPage to the AbsoluteLayout

    You could wire up either option in OnAppearing and unwire again in OnDisappearing, but I would wire it up in the first call to OnAppearing for an instance of a page (and not in subsequent calls to OnAppearing for that instance) and unwire in a handler for NavigationPage.Popped

Sign In or Register to comment.