What's a common way for creating "in place" popups within Xamarin.Forms app layout.

boleslavboleslav Member ✭✭

Is there any common (well-known) approach for creating custom popups in my Xamarin.Forms app layout.
Under custom popups one of the examples is a custom spinner: full window grayed background and small square container with the spinner inside (a simplest version) and more complex - embedding some Xamarin.Forms control (which is bound to ViewModel).
(The goal of this is not creating a new spinner, but that's just as example).

I am sure, there is no other way but having a custom renderer for the popup itself, but is there any general way of embedding my XF control into this?
(Currently, I am adding this control as "IsVisible=false", and show it inside of the manually created (iOS) views).

The custom renderer needed as I need to place that popup over the whole content (including navigation and other bars).

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    rg.plugins.popups

  • boleslavboleslav Member ✭✭

    Hm... Partially, but not quite, I guess.
    This plugin is about embedding whole pages, but I don't need it. I just need small pieces (including, a control only embedding right in place of existing page). This one seems complicated approach.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    You said "popup". Trust me when I say that is a really good nuget and approach.
    You describe a full page popup with grayed background that covers the current page and displays something: For example an ActivityIndicator. That describes exactly this package and use.

    I am sure, there is no other way but having a custom renderer for the popup itself

    I would never go that route.

    Just make a BusyPopup, and use it from whatever page you want. The idea is it should be reusable and not just part of a single page. That's good practice.

    If you just want something inside your existing page you can add a control in your page and toggle its IsVisible property.

    But I find your description a bit... confused. You say 'embedded in the page' then you describe 'full screen covering the entire page'. I'm not sure that you're sure what it is you need.

    This one seems complicated approach.

    Its not. And the more you use it the less complicated you'll see it is for use throughout your app.

  • boleslavboleslav Member ✭✭
    edited April 2018

    I guess, the thing is that you not quite attentive to what I actually mentioned. Or mixing up different things. I haven't mentioned "full page" (please re-read my question carefully). Instead, I was mentioning "full window", which are initially different instances: "window" is an UI element, when "page" is XF-referred logical structure.

    The reason why I can't use

    If you just want something inside your existing page you can add a control in your page and toggle its IsVisible property.

    ... is actually my this whole question. You cannot achieve full window covering (including navigation bars) with it (from UI perspective).

    But in case of using the plugin you've mentioned, it complicates my existing page logic. And this is not only about the page itself, but also ViewModel-s architecture. I don't need new custom page creation for displaying the custom confirmation box (with two-three labels) which expect to be used only on this very page, and where I can easily Bind one-two properties from current ViewModel.

    In addition, it has nothing to do with a problem of reusing. Vise verse, if there is some such universal control, which can host my StackLayout element, for instance, and display it withing this popup, that would be totally fine.
    Actually, I already do that with my custom code. I've got some service which receives the native (already generated UIView) and displays it inside of the container inserted into RootViewController (for iOS).
    But this code is still custom, and I am wondering if some developers already handle that in some "more standard" way...

  • boleslavboleslav Member ✭✭
    edited April 2018

    Not sure why are you referring to a word "fight".
    You've provided a solution which doesn't fully fit into the question requirements. I appreciate your efforts.
    I've also provided the details why the solution suggested is not quite what I am looking for.

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    If you have an example of what you are trying to achieve, post a picture.

    Because I read this whole thread a few times, and so far I agree with Clint that you are looking for his suggested plugin.

  • ChrisColeTechChrisColeTech USMember ✭✭✭
    edited April 2018

    It sounds like you are looking for a popup modal, no?

    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/navigation/modal

    Popup modal's cover the entire screen - including the title bar, etc.

    Couldn't you create a new XAML file and add your layout to it, and display it as a modal?

    side note:
    I tried out rg.plugins.popups back when I was trying to do a "loading" popup..it didn't serve my purposes either.

    I ended up using the Telerik Xamarin UI controls to get the loading spinner. Telerik has a bunch of controls for Xamarin - Perhaps that 3rd party library might have something useful for you? (https://www.telerik.com/xamarin-ui)

  • boleslavboleslav Member ✭✭
    edited April 2018

    Thanks for responding, but the picture wouldn't help as in general it does look like the example from the plugin mentioned, i.e., this.
    https://github.com/rotorgames/Rg.Plugins.Popup/blob/master/img/popup-landing.png - it's from github.

    However, the way I should use this plugin, i.e.

    To open a popup page you should create new class or xaml file and extend it from Rg.Plugins.Popup.Pages.PopupPage

    is not quite the an approach I am looking for. It's complicated, it requires me to create a new PopupPage every time I need a small alert box (let's call it), and I cannot bind any properties from my current ViewModel to the content on this popup directly.

  • boleslavboleslav Member ✭✭
    edited April 2018

    Thanks Chris!

    In general, yes. This is what can be achieved with Telerik, I guess. (Xamarin modal popups is also kind of the rg.plugin approach).
    And I did have one project which used it for actually showing custom progress view.
    However, unfortunately Telerik is very expensive (especially, for such small functionality), as far as I know.
    Secondly, it's quite "heavy" (as in terms of the controls speed work, as output binary size growing).

    And, again, I've already implemented it in some way. Just wanted to be sure I wasn't re-inventing a simple bicycle...

  • ChrisColeTechChrisColeTech USMember ✭✭✭

    @boleslav said:
    Thanks for responding, but the picture wouldn't help as in general it does look like the example from the plugin mentioned, i.e., this.
    https://github.com/rotorgames/Rg.Plugins.Popup/blob/master/img/popup-landing.png - it's from github.

    However, the way I should use this plugin, i.e.

    To open a popup page you should create new class or xaml file and extend it from Rg.Plugins.Popup.Pages.PopupPage

    is not quite the an approach I am looking for. It's complicated, it requires me to create a new PopupPage every time I need a small alert box (let's call it), and I cannot bind any properties from my current ViewModel to the content on this popup directly.

    I see what you're saying. I agree with it being overly complicated - and for your situation you would get 'very limited' re-use out of the popup. You would either have to create a view model for each 'popup', or do something weird behind the scenes to bind your properties everytime the 'popup' appears.

    Unfortunately there is no silver bullet to solve your problem - you're going to have to come up with something , either a custom solution, or a combination of custom code and the plugin(s) provided.

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    If you want dynamic content in the Rg.Plugins.Popup, it is pretty straightforward to set the Content of a popup page to any Xaml you want, and write a wrapper method to call Popup.Show(xamlView, viewModel);

  • boleslavboleslav Member ✭✭

    Adam, I guess Chris in prev comment described my concerns great as well.

    It's cool the plugin allows to do the custom xaml showing, but it seems also quite a complication (especially if you use current ViewModel's properties bound to this object).

    Actually, I've realized that I've kind of seen the approach required with Telerik in one of the projects (when you just wrap your content you need to display inside of the "popup" (I mentioned popup in quotes here)), but again, this is Telerik and its disadvantages I've mentioned above.

    In my custom solution I already do the same. So if there won't be any other (existing) solutions provided, I should probably build some sort of such component and upload it to github to make it reusable.

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    If you do end up building something, check back in when you do. I would be interested to see if it fits my needs in projects better or worse than my current usage.

  • AlmaJensen.9398AlmaJensen.9398 USMember ✭✭✭

    Your mileage may vary with this approach but trying using a modal page with a transparent background. One time while just playing around I did that and the previous page would be visible behind the transparent Modaly pushed page. I never used it in a final solution so I wouldn't garentee this option.

    You could also try this.
    https://michaelridland.com/xamarin/announcing-slideoverkit-for-xamarin-forms/

    I think Syncfusion might have a similar control as well and it's much cheaper than Telerik

  • PrabakaranRamasamyPrabakaranRamasamy USMember ✭✭✭

    @boleslav try out the brand new lightweight pop-up layout from Syncfusion. I am sure that it meets your requirements.

    https://www.syncfusion.com/products/xamarin/popup

    You can create the pop-up layout in just few lines of code.

    https://help.syncfusion.com/xamarin/sfpopuplayout/getting-started

    The whole suite of controls is available for free (commercial applications also) through the community license program if you qualify (less than 1 million US Dollars in revenue). The community license is the full product with no limitations or watermarks.

    Note: I work for Syncfusion.!

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Ok. So its another popup framework. I'm not seeing how it is more what you're looking for than rg.plugins.popups... other than its a commercial product so they did a bunch of grunt work by pre-creating several commonly used layouts. Unless I'm missing something it really is the same. Its just a different brand of popup system. Kind of like how a Honda and Volkwagen are the same only different. Do you like the speedometer on the left or right of the tachometer?

    I guess this thread has just determined the next article for my tutorial site: Implementing a popup mechanism.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @boleslav said:
    is not quite the an approach I am looking for. It's complicated, it requires me to create a new PopupPage every time I need a small alert box (let's call it), and I cannot bind any properties from my current ViewModel to the content on this popup directly.

    Then you really aren't grasping it. Which is fine. Nobody grasps something new until they start using it. But its not complicated and you don't have to create a new popup every time you want to show an alert. I have system-scoped alerts in my apps and I re-use them. Make it static and its even simpler.

    and I cannot bind any properties from my current ViewModel to the content on this popup directly.

    sure you can. Why can't you? I do it. I have popups that come up telling the user how may Widgets they have, do they want to want more... binded names in the popups so they are friendly "Bob, you have 7 messages. Do you want to read them now?" Bob and 7 are both binded values from the VM that called the popup.

    I think you're just falling for the slick webpage they put up making it look like no coding knowledge is required.

  • boleslavboleslav Member ✭✭

    sure you can. Why can't you? I do it. I have popups that come up telling the user how may Widgets they have, do they want to want more... binded names in the popups so they are friendly "Bob, you have 7 messages. Do you want to read them now?" Bob and 7 are both binded values from the VM that called the popup.

    @ClintStLaurent, could you provide an example (including, having this binding inside of "parent" page (xaml))?

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    I can't provide code from my work projects: That's all NDA and company I.P.

    But its just binding. Nothing magical or out of the ordinary about it. You make a property on the popup, or if the popup has its own VM then on that...

    Or you could just have the popup use the same VM as the calling page for its BindingContext. That might be the easiest way. After all the popup probably won't use more than 5 properties anyway. Just have the popup and the page share the same VM.

  • boleslavboleslav Member ✭✭
    edited April 2018

    @ClintStLaurent, when you are referring to popup, what do you mean exactly by that? Is this something derived from the PopupPage, and using it in xaml like the example above?

    <controls:myPopupClass BindingContext="{Binding SomePropertyOfMyViewModel}"/>

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    BindingContext="{Binding SomePropertyOfMyViewModel}"

    That concerns me. BindingContext should be an object... A class. Generally a ViewModel. Rarely a property on a ViewModel, unless it happens to be another class object - which is totally legal. Like having an Employee on the StaffRosterViewModel

    when you are referring to popup, what do you mean exactly by that?

    A view that will appear to pop up over the existing view. For example: You have a LogInView with username and password. When the user hits [submit] a popup will cover the screen with a message such as "please wait, logging you in" and maybe an ActivityIndicator to let them know its not frozen. My preference for popups is to have the background be fullscreen and maybe 60% gray so the user can see through to the Page below, yet it covers and blocks the Page below so they can't bang on the buttons. However I've used the same concept without the background in order to have a smaller control like a ListView to carefully place below a button so it looks like a drop down menu which doesn't exist in mobile devices.

    using it in xaml like the example above?

    IN MY USAGES Its is separate from the page. Not a child of the page. Thought it would be totally legal to make it a child of the page and just toggle its IsVisible property. Personally that feels a little dirty for a generics description of using a popup - but there are always exceptions.

    The problem I have with making it a child is that the logic for its use still has to come down to the ViewModel - and that shouldn't know anything about what is in the View.

    The ViewModel should be able to call up a new BusyIndicatorPopup as needed, regardless of what page is on top at the moment. If your popup is a control that is part of the page then how and from where are you deciding to show it? Where is that logic? On the code behind of the page: Because that's probably crossing the line into bad practices.

  • boleslavboleslav Member ✭✭

    Actually, @ChrisColeTech already mentioned the concerns why embedding of the page is not quite handy (and overcomplicated) in this case.

    As I've also mentioned, (and in contrast of the logic of embedding another page, which would require some specific functionality to appear inside of that page), I need the control showing in the popup to be a part of current page (thus, current ViewModel).

    If this is just a box (kind of customized confirmation), which has three lines of (xaml) code like "are you sure you want to ...?" with one-two properties bound to the current ViewModel. And yes, it can be driven via IsVisible (it already is in my existing code). And I can't see anything wrong with the architecture. Everything is defined right at place (of current page and current ViewModel), like this:

                            <controls1:PopupBox 
                                WidthRequest="200" HeightRequest="200" 
                                IsVisible="{Binding IsConfirmationActive}">
                                    <StackLayout>
                                        <Label Text="Confirm Your In-App Purchase"/>
                                        <Label Text="Do you want to buy this chapter for"/>
                                        <Label Text="{Binding CurrentlyBuyingChapter.Price, StringFormat='${0}'}"/>
    
                                        <Button  Command="{Binding GoConfirmChapterBuying}" Text="Buy Chapter"/>
                                    </StackLayout>
                                </StackLayout>
                            </controls1:PopupBox>                
    

    As you've previously mentioned, in general it's completely the same as I would have a common View with IsVisible, but not covering Navigation (and other) bars. But this does. So, no difference from architectural perspective.

Sign In or Register to comment.