We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Execute a popup from a viewmodel

I would like to use the SF Popup like an Alert Box/Userdialog in MVVM. It would be nice to be able to call a method like DisplayAlert(header_title, body_text, accept_button_text, decline_button_text) which somehow calls the Popup in the View and displays the Alert. How would I achieve executing this popup from the ViewModel?

9 Replies

BS Balasubramani Sundaram Syncfusion Team November 12, 2019 09:51 AM UTC

Hi Reza,    
   
Thank you for contacting Syncfusion support.     
   
Your requirement to show the SfPopupLayout like an alert box from the view model can be achieved by using “On the go” support in SfPopupLayout. In the “On the go” support we must initialize the renderer in all three platforms for more information please refer the below link.   
   
In the sample, we set the SfPopupLayout.PopupView.AutoSizeMode as Height to auto-resize, if this not need please ignore it.   
   
Please refer the below code snippet, sample and UG Link.     
   
   
   
Code Snippet [C#]   
   
[MainPage.Xaml.cs]   
   
private ViewModel _viewModel;   
public MainPage()   
{   
    _viewModel = new ViewModel();   
}   
   
private void clickToShowPopup_Clicked(object sender, EventArgs e)   
{   
    _viewModel.DisplayAlert("Issue", "Can't open this page", "Ok", "Cancel");   
}   
   
[ViewModel.cs]   
public class ViewModel   
{   
   
    private SfPopupLayout popupLayout;   
    public ViewModel()   
    {   
        popupLayout = new SfPopupLayout ();   
    }   
   
    public void DisplayAlert(string displayText, string bodyText, string accepttext,string declinetext)   
    {   
        ......   
        popupLayout.PopupView.HeaderTitle = displayText;   
        popupLayout.PopupView.ContentTemplate = contentTemplateView;   
        popupLayout.PopupView.ShowFooter = true;   
        popupLayout.PopupView.ShowCloseButton = false;   
        popupLayout.PopupView.AutoSizeMode = AutoSizeMode.Height;   
        popupLayout.PopupView.AppearanceMode = AppearanceMode.TwoButton;   
   
        //// Configure our Accept button   
        popupLayout.PopupView.AcceptButtonText = accepttext;   
        popupLayout.PopupView.AcceptCommand = new Command(() =>   
        {   
            popupLayout.IsOpen = false;   
        });   
        popupLayout.PopupView.PopupStyle.AcceptButtonTextColor = Color.Black;   
        popupLayout.PopupView.PopupStyle.AcceptButtonBackgroundColor = Color.White;   
   
        // Configure our Decline button   
        popupLayout.PopupView.DeclineButtonText = declinetext;   
        popupLayout.PopupView.DeclineCommand = new Command(() =>   
        {   
            popupLayout.IsOpen = false;   
        });   
        popupLayout.PopupView.PopupStyle.DeclineButtonTextColor = Color.Black;   
        popupLayout.PopupView.PopupStyle.DeclineButtonBackgroundColor = Color.White;   
   
        // Show the popup and wait for user to close   
        popupLayout.IsOpen = true;   
    }   
}   
   
  
   
   
     
   
Please let us know, if you need any further other assistance from us.   
   
Regards,
Balasubramani Sundaram 
 



RM Reza Mohamed November 13, 2019 11:07 PM UTC

Thanks - this works.

Is there a similar way to launch the SfBusyIndicator from the view model as well?

In addition, can you help me understand where the busyIndicator control needs to be placed if I have a Grid inside the ContentPage that is showing content please? While I'm retrieving content I would like to show the Busy Indiccator on the middle of the screen.

eg.

     < ContentPage.Content >
             < Grid >
       ...grid items here

     < /ContentPage.Content >
             < /Grid >
     

In the above, I have tried placing the busyIndicator control inside the grid and outside, but fails to compile.

Thanks


HM Hemalatha Marikumar Syncfusion Team November 14, 2019 10:40 AM UTC

Hi Reza,

Thanks for the update.

We have created a ListView along with the SfBusyIndicator in a Grid. When the Button is invoked the SfBusyIndicator will be shown in the middle of the page until the listview is loaded with the time delay. Please have the sample from the below link,

Sample Linkhttps://www.syncfusion.com/downloads/support/directtrac/general/ze/BusyIndicatorCenter1255200005

Code Snippet[XAML]: 
 <ContentPage.Content>

 
        <Grid> 
             <Button x:Name="Button" Text="Login"/> 
             <ListView x:Name="listView" IsVisible="false"> 
                <ListView.ItemTemplate> 
                    <DataTemplate> 
                        <ViewCell> 
                            <StackLayout HeightRequest="40"> 
                                <Label Margin="10,7,0,0" Text="{Binding}" FontSize="16" /> 
                            </StackLayout> 
                        </ViewCell> 
                    </DataTemplate> 
                </ListView.ItemTemplate> 
            </ListView> 
            <busyindicator:SfBusyIndicator x:Name="busyindicator" AnimationType="Battery" ViewBoxWidth="50" IsBusy="{Binding IsBusy}" IsVisible="{Binding IsVisible}" ViewBoxHeight="50" TextColor="Maroon" /> 
        </Grid> 
    </ContentPage.Content> 


Please check with the above and let us know if you have any concerns. 
 
Regards, 
Hemalatha M. 



RM Reza Mohamed November 14, 2019 03:07 PM UTC

In your sample, you had not specified the Grid Row and Column Definitions. In a case where those ar specified the BusyIndicator does not show on the middle of the screen. This was my use case, how would you be able to do that? 

Also, from my first reply, is there a way to create/display the BusyIndicator directly from the ViewModel without having XAML Code like for the PopupAlert solution above?

<ContentPage.Content>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="50" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>

            <Button x:Name="Button" Text="Login" IsVisible="true" Grid.Row="0"/>
             <ListView x:Name="listView" IsVisible="false" Grid.Row="1">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout HeightRequest="40">
                                <Label Margin="10,7,0,0" Text="{Binding}" FontSize="16" />
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <busyindicator:SfBusyIndicator x:Name="busyindicator" AnimationType="Battery" ViewBoxWidth="50" IsBusy="{Binding IsBusy}" IsVisible="{Binding IsVisible}" ViewBoxHeight="50" TextColor="Maroon" />
        </Grid>
    </ContentPage.Content>


HM Hemalatha Marikumar Syncfusion Team November 15, 2019 12:09 PM UTC

Hi Reza, 
  
We have checked your requirement “SfBusyIndicator directly from the ViewModel without having XAML Code” from our side. We have created a sample with SfBusyIndicator inside the SfPopUpLayout view to achieve the same. 
   
Code Snippet [XAML]: 
..  
            DataTemplate contentTemplateView = new DataTemplate(() => 
            { 
                StackLayout stack = new StackLayout(); 
                busyIndicator = new SfBusyIndicator(); 
                busyIndicator.IsBusy = true; 
                stack.Children.Add(busyIndicator); 
                return stack; 
            }); 
  
 
        } 
    } 


 


 
Output:

 
     

 


 
Sample Link: 


 
Please check with the above and let us know if you have any other queries. 
 
Regards, 
Hemalatha M. 



RM Reza Mohamed December 2, 2019 08:35 PM UTC

I am actually trying to render this while a page is opening and the components are getting displayed as well as pulling data from an API service. How best would it be possible to leverage the Busy Indicator to show the Busy Indicator while the page components are loading? 


HM Hemalatha Marikumar Syncfusion Team December 3, 2019 02:31 PM UTC

Hi Reza, 
  
Thanks for your update. 
  
We would like to inform you that, SfBusyIndicator same as the ActivityIndicator. So, using the IsBusy property you can show or collapse the SfBusyIndicator. Using this property, you can show the indicator while loading and also when retrieving the data from the API service.

Please try this scenario in your application and let us know if you have any other queries.
 
 
Regards, 
Hemalatha M. 



RM Reza Mohamed December 3, 2019 07:56 PM UTC

Using the code from one of the above replies I was able to create a method to show Busy, ShowBusy is defined in my ViewModelBase along with two private fields.

private SfPopupLayout _popupLayout;
private SfBusyIndicator _busyIndicator;

This works just fine when the app is loaded and something is already presented on the view.

protected void ShowBusy(bool show)
{
    //TODO putting this in try catch because there is an error depending on page lifecycle
    try
    {
        DataTemplate contentTemplateView = new DataTemplate(() =>
        {
            StackLayout stack = new StackLayout();
            _busyIndicator = new SfBusyIndicator();
            _busyIndicator.ViewBoxHeight = 100;
            _busyIndicator.ViewBoxWidth = 100;
            _busyIndicator.IsBusy = true;
            stack.Children.Add(_busyIndicator);
            return stack;
        });
 
        _popupLayout.PopupView.HeaderTitle = string.Empty;
        _popupLayout.PopupView.ContentTemplate = contentTemplateView;
        _popupLayout.PopupView.ShowHeader = false;
        _popupLayout.PopupView.PopupStyle.BorderColor = Color.Transparent;
        _popupLayout.PopupView.ShowFooter = false;
        _popupLayout.PopupView.ShowCloseButton = false;
        _popupLayout.PopupView.AutoSizeMode = AutoSizeMode.Height;
        _popupLayout.PopupView.BackgroundColor = Color.Transparent;
 
        _popupLayout.IsOpen = show;
 
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        //Crashes.TrackError(e);
    }
 
}

However, I can't execute this message in the OnNavigatedTo method (PRISM) in a ViewModel that extends ViewModelBase, or really any other method until the ContentPage is presented. I am looking for some help on showing this busyindicator while the ContentPage is getting created and the API web service calls are getting pulled.



Do you have a sample of how to execute this while pages are getting loaded?


HM Hemalatha Marikumar Syncfusion Team December 4, 2019 10:31 AM UTC

Hi Reza, 
 
Thanks for your update but we are not clear about your exact scenario “I am looking for some help on showing this busy indicator while the ContentPage is getting created and the API web service calls are getting pulled”. – Are you want to show the SfBusyIndicator while navigating the page? 
 
We have prepared the sample based on that and find in below link 
 
From the attached screenshot, we have understood that you have loading the SfBusyIndicator inside the Popup layout. With this case, we have already provided sample. If you are facing any of crash issue, then please share the complete stack trace to find the exact issue and if possible to provide a fix for that.

Please check with the above sample and video and if the mentioned issue differs please provide the issue reproducing sample which will be helpful for us to analyze further and provide an appropriate solution. 
 
Regards, 
Hemalatha M. 
 


Loader.
Live Chat Icon For mobile
Up arrow icon