New Page from Custom Renderer

Hi,

I need help in calling a new page from a custom renderer I'm running on iOS.

Thanks!

Answers

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    @DiegoEstevez - If you want to move to a new page I wouldn't do it in the CustomRenderer.

    The Control that you are rendering should have a function or something that can be called and the control can then start a page change if necessary.

    e.NewElement.NewPage()

    This way you are back in Xamarin Forms and doing your navigation from there.

  • DiegoEstevezDiegoEstevez USMember

    @AdamP said:
    @DiegoEstevez - If you want to move to a new page I wouldn't do it in the CustomRenderer.

    The Control that you are rendering should have a function or something that can be called and the control can then start a page change if necessary.

    e.NewElement.NewPage()

    This way you are back in Xamarin Forms and doing your navigation from there.

    Thanks you @AdamP for trying to help me. I tried writing e.NewElement.NewPage() under my protected override void OnElementChanged(VisualElementChangedEventArgs e), but NewPage() is not found.

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    He is saying put a method in your subclass that you are making a renderer for.

    public class SubclassedView : Page
    {
        public async Task StartNewPage()
        {
            await Navigation.PushAsync(new SecondPage());
        }
    }
    
    public class SubclassedViewRenderer : PageRenderer
    {
        public void SomeMethod
        {
            // ... In some method when you want to call it.
            ((SubclassedView)Element).StartNewPage();
        }
    }
    
  • DiegoEstevezDiegoEstevez USMember

    @AdamMeaney said:
    He is saying put a method in your subclass that you are making a renderer for.

    public class SubclassedView : Page
    {
        public async Task StartNewPage()
        {
            await Navigation.PushAsync(new SecondPage());
        }
    }
    
    public class SubclassedViewRenderer : PageRenderer
    {
        public void SomeMethod
        {
            // ... In some method when you want to call it.
            ((SubclassedView)Element).StartNewPage();
        }
    }
    

    Not working at all. Did exactly what you told me :s

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    Post some code then. Because this is pretty standard code, should work with a little tweaking.

  • DiegoEstevezDiegoEstevez USMember
    edited July 2016

    @AdamMeaney said:
    Post some code then. Because this is pretty standard code, should work with a little tweaking.

    Here you are. Hope it helps. I tried calling it from OnElementChanged but I'm getting an error and, wherever I put it, I'm getting the warning of putting adding to it an await. However, if I add it, the await does not exist in the current context.

    [assembly: Dependency(typeof(startPageRenderer))] [assembly: ExportRenderer(typeof(startPage), typeof(startPageRenderer))] namespace testNamespace.iOS { public class SubclassedView : Page { public async Task StartNewPage() { await Navigation.PushAsync(new MainPage()); } } public class startPageRenderer : PageRenderer { /*Called from dependency system coming from PCL. There is some other code running here which I have not copied. That code is the reason why Im using a custom renderer */ public void Connection(string id) { ((SubclassedView)Element).StartNewPage(); } } }

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    Alright, let's start:

    You have a class somewhere called startPage. That is the location that the method StartNewPage should be on.

    Then in the startPageRenderer, you should cast the Element to startPage before use.

    Put a breakpoint in to make sure that the Connection method is actually called.

  • DiegoEstevezDiegoEstevez USMember
    edited July 2016

    @AdamMeaney said:
    Alright, let's start:

    You have a class somewhere called startPage. That is the location that the method StartNewPage should be on.

    Then in the startPageRenderer, you should cast the Element to startPage before use.

    Put a breakpoint in to make sure that the Connection method is actually called.

    I moved the StartNewPage to the startPage.xaml.cs and changed the cast to startPage, but Im getting a NullReferenceExeption.

    [assembly: Dependency(typeof(startPageRenderer))] [assembly: ExportRenderer(typeof(startPage), typeof(startPageRenderer))] namespace testNamespace.iOS { public class startPageRenderer : PageRenderer { /*Called from dependency system coming from PCL. There is some other code running here which I have not copied. That code is the reason why Im using a custom renderer */ public void Connection(string id) { ((startPage)Element).StartNewPage(); } } }

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    Do you have a startPage being displayed on the screen?

    If the startPage is not on screen, the page renderer is probably not finished being setup, so the Element is null.

    I don't understand quite why you have a dependency service thing going on here, as the renderer is supposed to be calling the method when whatever else you are doing is done.

    You cannot just call a method on the renderer when it is not attached to the view yet.

  • DiegoEstevezDiegoEstevez USMember

    @AdamMeaney said:
    Do you have a startPage being displayed on the screen?

    If the startPage is not on screen, the page renderer is probably not finished being setup, so the Element is null.

    I don't understand quite why you have a dependency service thing going on here, as the renderer is supposed to be calling the method when whatever else you are doing is done.

    You cannot just call a method on the renderer when it is not attached to the view yet.

    I moved it to ViewDidAppear and worked like a charm! Though I would need to have it under the Connection void, with other code as well, to trigger it from another script in PCL.
    Any idea? Thanks you :)

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    Right, if you have a PageRenderer, you have to call it sometime after the renderer attached.

    Usually, I recommend the page just have an event that the renderer is listening to, and whenever you fire the event the connection method is run.

    This makes it so you can call it from the PCL on the Forms side by firing the event, probably anytime after OnAppearing of the page.

  • DiegoEstevezDiegoEstevez USMember
    edited July 2016

    @AdamMeaney said:
    Right, if you have a PageRenderer, you have to call it sometime after the renderer attached.

    Usually, I recommend the page just have an event that the renderer is listening to, and whenever you fire the event the connection method is run.

    This makes it so you can call it from the PCL on the Forms side by firing the event, probably anytime after OnAppearing of the page.

    And how do you suggest doing this? The only problem is that I would need to run it from inside a ContinueWith().

    Sorry for asking this kind of questions, Im new to all these and I wanna learn :s

Sign In or Register to comment.