how to extend all contentpages with pagerenderer?

batmacibatmaci DEMember ✭✭✭✭✭

I want to add some native controls for all my contentpages for UWP. for that i created a customcontrol in uwp level and tried with the code below. is that how it supposed to be? is that the best way? so i just add a stacklayout around main XF content and nativecontrols. I am also not sure how to avoid if it is already created because i recognized that it is called even control is already created.

[assembly: ExportRenderer(typeof(ContentPage), typeof(myWorkout.UWP.Renderers.ContentPageRenderer))]
namespace myApp.UWP.Renderers
{

    public class ContentPageRenderer : PageRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Page> e)
        {
            base.OnElementChanged(e);


                if (e.OldElement != null || Element == null)
                {
                    return;
                }

                ContentPage page = ((ContentPage)Element);
                if (page.Content == null)
                    return;

                var NativeControls = new Views.NativeInfoView();
                StackLayout stackLayout = new StackLayout() { Orientation = StackOrientation.Vertical };
                stackLayout.Children.Add(page.Content);
                stackLayout.Children.Add(NativeControls.ToView());

                page.Content = stackLayout; 
            }

    }
}

Best Answer

Answers

  • batmacibatmaci DEMember ✭✭✭✭✭

    thank @JohnHardman. i think that 1 is the best option to create a basepage and change each and every contentpage with uwp condition. this will be more work for me. project is quite large with many contentpages.
    2) i am not sure if i understand 2nd one. could you give me a sample if there is one?

  • JohnHardmanJohnHardman GBUniversity mod

    @batmaci said:
    2) i am not sure if i understand 2nd one. could you give me a sample if there is one?

    I currently do (1). When I come to optimization, I'll replace some of the pages created using (1) by native implementations (UWP, Android, iOS) as required to get acceptable response times. As a stepping stone to that, I might do (2) at some point, but it's unlikely to be soon.

    My nightly backup has just started, so I'll leave putting together a clearer explanation of (2) until the morrow. If I forget, or seem to forget, feel free to remind me :-)

  • JohnHardmanJohnHardman GBUniversity mod
    edited February 13

    @batmaci

    Some examples of using (2):

    On iOS, using a custom PageRenderer that adds iOS native controls to convert the display of any secondary toolbar items into a dropdown menu instead of the default display of secondary toolbar items. The ContentPages do not know that these extra native controls have been added, and the renderer does not change the ContentPages.

    On iOS, using a custom PageRenderer that adds iOS native controls to create a back button composed of an image and text. Again, the ContentPages know nothing of the extra native controls, and the renderer does not change the ContentPages.

    Cross-platform, using custom renderers to add a SearchBar to the top of every page. On UWP, a ContentPage renderer could instantiate a new FrameworkElement and in that FrameworkElement could add an AutoSuggestBox and the FrameworkElement that would have been used for the ContentPage's Content. That way, the renderer is rendering an AutoSuggestBox and the original page content, but without making any changes to the ContentPage itself.

    All of these can be done other ways, but hopefully give an idea of how PageRenderers can be used to give consistency between multiple pages.

  • batmacibatmaci DEMember ✭✭✭✭✭

    @JohnHardman thanks for your help. my idea was to manipulate all Content of the Contentpages without any code change in XF code. because my requirement is only for UWP. but it doesnt seem to be possible. Because OnElementChanged is called more than 1 time. So i decided to go with the way you suggested. I created customView in XF and View renderer like below. This is easy implementation when we need to implement for all 3 platforms. I wish that there was a way to implement such platform specific implementation without doing any change on forms project. eventually XF meant to be shared code but my below CustomView is not shared. it belongs to only UWP as I want to use it only in my UWP project.

         public class CustomView : Xamarin.Forms.View
            {
            }
    
            protected override void OnElementChanged(ElementChangedEventArgs<CustomView> e)
                {
                    base.OnElementChanged(e);
                    if (isDisposing)
                        return;
    
                 if (Control == null && Element != null && e.OldElement == null)
                    {
                        var MyUserControl1 = new MyUserControl1();
                        SetNativeControl(MyUserControl1);
                    }
                }
    
  • JohnHardmanJohnHardman GBUniversity mod

    @batmaci said:
    @JohnHardman thanks for your help. my idea was to manipulate all Content of the Contentpages without any code change in XF code. because my requirement is only for UWP. but it doesnt seem to be possible.

    It is possible. Whether it's the best approach depends on the exact requirements.

    @batmaci said:
    Because OnElementChanged is called more than 1 time

    In the different calls to OnElementChanged, which of the following are null and which are non-null on each call?

    Control, Element, e.NewElement, e.OldElement

  • batmacibatmaci DEMember ✭✭✭✭✭

    unfortunately i dont see any difference. thats why it makes the things harder. I just created a small test project. you can see what i mean choosing same page 2 times in masterdetail.

Sign In or Register to comment.