3

how to add a nice timer
xaml :

 <ProgressBar x:Name="progressBar" Grid.Row="2" Grid.ColumnSpan="5"
                    IsVisible="true"
                    Progress="0.0"
                    WidthRequest="300"
                    HeightRequest="20"
                    VerticalOptions="Center"
                    HorizontalOptions="Center">
                </ProgressBar>

behind code:

progressBar.Progress = 0;
await progressBar.ProgressTo(1.0, 90000, Easing.Linear);
1
  • you need to use a Timer
    – Jason
    Commented Dec 9, 2017 at 23:11

1 Answer 1

3

You can use a timer to increment the ProgressBar:

var updateRate = 1000 / 30f; // 30Hz
double step = updateRate / (2 * 30 * 1000f);
Device.StartTimer(TimeSpan.FromMilliseconds(updateRate), () =>
{
    if (progressBar.Progress < 100)
    {
        Device.BeginInvokeOnMainThread(() => progressBar.Progress += step );
        return true;
    }
    return false;
});

Then you can use an IValueConverter to convert the progress to a minute:second style format:

public class CountDownConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double time = 0;
        double.TryParse(parameter.ToString(), out var totalTime);
        double.TryParse(value.ToString(), out var progress);
        time = progress <= double.Epsilon ? totalTime : (totalTime - (totalTime * progress));
        var timeSpan = TimeSpan.FromMilliseconds(time);
        return $"{timeSpan.Minutes:00;00}:{timeSpan.Seconds:00;00}";
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Tying it together with XAML:

<Label
    BindingContext="{x:Reference progressBar}"
    Text = "{Binding Progress, StringFormat='{0:P0}'}"
    HorizontalOptions ="Center"
    FontSize="20"
    FontFamily = "Helvetica Neue"
    TextColor ="Red" />
<ProgressBar x:Name="progressBar"
    IsVisible="true"
    Progress="0.0"
    WidthRequest="300"
    HorizontalOptions="Center">
</ProgressBar>
<Label Text="{Binding Source={x:Reference progressBar},
                      Path=Progress,
                      Converter={StaticResource countDownTime},
                      ConverterParameter=120000}}"
    HorizontalOptions ="Center"
    FontSize="20"
    FontFamily = "Helvetica Neue"
    TextColor = "Red" />

Output:

enter image description here

Update:

You have to define a ResourceDictionary to have an instance of the CountDownConverter class created and named so you can reference it in XAML:

<ContentPage.Resources>
    <ResourceDictionary>
        <tools:CountDownConverter x:Key="countDownTime"/>
    </ResourceDictionary>
</ContentPage.Resources>

And the tools: namespace reference is based upon the C# namespace and assembly that contains the CountDownConverter. I have a bunch of these IValueConverter classes in a separate library and thus my xmlns:tools looks like:

xmlns:tools="clr-namespace:Converters;assembly=Converters"

re: Resource Dictionaries

9
  • Thank you so much @SushilHangover ! I got an error on this line . I know is because I havent define this resource . how could I fix it : Converter={StaticResource countDownTime},
    – Pxaml
    Commented Dec 11, 2017 at 18:35
  • what I am trying to say is that I got this error: Cannot assign property "ConverterParameter": Property does not exists, or is not assignable, or mismatching type between value and property., and maybe it was because I didn't set this resource correctly ?.Thank you for reply
    – Pxaml
    Commented Dec 11, 2017 at 18:44
  • Amazing solution, the only problem for me is that the refresh rate its wrong it's not actually seconds so the time shown on the label is not correct Commented Mar 17, 2018 at 20:54
  • @JoseManuelOjeda Not sure I understand if you had a problem or not, solved it? Commented Mar 17, 2018 at 21:48
  • 1
    @11thal11thal If you have a fixed time period 0 to 5 seconds and want to update the UI at a 30Hz (33ms) rate, than 5 * 1000 / 33 = 151 steps. Since a progress bar values are 0 to 100, 100 / 151 = 0.66 step increase every 33ms. Commented Aug 18, 2020 at 1:31

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.