Quantcast
Channel: Recent Threads — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 204402

Xamarin.Forms Update ActivityIndicator Text From ViewModel Not Working?

$
0
0

Hi,

I am very new to Xamarin.Forms and C# in general and have a very basic app that I cannot get working as I want it to. All the app has is 1 page, with an ActivityIndicator and a Button. Clicking the button starts a "long process" but is really just starting a for-loop with a delay that slowly increases the % complete (in the actual app I want to make, it will start a async process that stores a lot of data in a DB). Since this process will take awhile, I want the ActivityIndicator Text to gradually let the user know how far along in the process they are. The current app uses a Binding on the ActivityIndicator Text, this Text is updated via the Binding from the ViewModel. This is working when I just set the inital value to 0. However, when I start a for-loop with a Task.Delay() call inside it, the ActivityIndicator Text does not update when I set the value of the Binding variable from within the loop. If I do not add the Task.Delay() call, the Binding works and the ActivityIndicator gets set to 100%.

So I have a MainPage.xaml class that looks as follows:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="ProgressUpdateTest.MainPage">

    <AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <StackLayout IsVisible="{Binding IsBusy}" 
                     Padding="12"
                     AbsoluteLayout.LayoutFlags="PositionProportional"
                     AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1">

            <ActivityIndicator IsRunning="True"/>

            <Label Text="{Binding PercentComplete, StringFormat='{0}% complete'}" 
                   HorizontalOptions="Center" 
                   TextColor="Black"/>

            <Button Clicked="Button_Clicked" 
                    Text="Start">
            </Button>

        </StackLayout>
    </AbsoluteLayout>
</ContentPage>

And MainPage.xaml.cs looks like this:

namespace ProgressUpdateTest
{
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {

        public MainPageViewModel mainPageViewModel;
        public MainPage()
        {
            InitializeComponent();
            mainPageViewModel = new MainPageViewModel();
            BindingContext = mainPageViewModel;
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            mainPageViewModel.Start();
        }
    }
}

With the ViewModel as follows:

namespace ProgressUpdateTest.ViewModel
{
    public class MainPageViewModel
    {
        private bool _isBusy;
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                _isBusy = value;
            }
        }

        private string _percentComplete;
        public string PercentComplete
        {
            get { return _percentComplete; }
            set
            {
                _percentComplete = value;
            }
        }

        private MainPageUseCase mainPageUseCase;

        public MainPageViewModel()
        {
            mainPageUseCase = new MainPageUseCase();
            IsBusy = true;
            PercentComplete = "0";
        }

        public async void Start()
        {
            for (var i = 1; i < 101; i++)
            {
                await Task.Delay(500);
                Console.WriteLine(i);
                Device.BeginInvokeOnMainThread(() =>
                {
                    PercentComplete = i.ToString();
                });
            }
        IsBusy = false;
        }
    }
}

The initial PercentComplete = 0 works, but the ones in the Loop do not. I have tried everything I could think of to debug this issue, but have had no luck. I believe this is happening because of my lack of knowledge about async and things of that sort with C#. I have tried this without the Device.BeginInvokeOnMainThread() call, changing the await Task.Delay(500) line to Task.Delay(500).Wait(), and a few other things and have not seen the ActivityIndicator move from 0%. The issue definitely has to do with the await Task.Delay(500) line, if I remove that then I can see the PercentComplete variable change when I change it to something after the initial PercentComplete = 0.

If anyone has any idea about what is going on and how I can fix it I would appreciate some help!

Thank you,
Ryan


Viewing all articles
Browse latest Browse all 204402

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>