Reputation: 1568
The Progress property of my ProgressBar is updated by the method named UploadProgressCallback, invoked by UploadProgressChanged event. Everything is working but I noticed that ProgressBar goes directly from 0 to 1, it seems not have a smoothly update and I resolved to analyze the operation output and realized the division of sent bytes by the file size is being truncated to 0, so some results that should be 0.234 or 0.643, goes to Progress property as "0" and it causes bar keeps stuck on initial point, when upload is completed, the division will obviously return 1 and the bar is filled. I tried a lot of things but output is always 0. Does anyone have an advice that can fix that?
ProgressBar view on xaml
<ProgressBar IsVisible="{Binding UploadProgressVisibility}" IsEnabled="{Binding UploadProgressVisibility}" FlowDirection="LeftToRight" ProgressColor="Orange" Progress="{Binding UploadProgress}" Grid.Column="0" Grid.Row="1" HeightRequest="20" WidthRequest="80" Margin="0" />
UploadProgressCallback
webclient.UploadProgressChanged += new UploadProgressChangedEventHandler((s,e) => UploadProgressCallback(s,e,idrefecence));
private void UploadProgressCallback(object sender, UploadProgressChangedEventArgs e, int idreference)
{
double temp = (double) e.BytesSent / filesize;
Device.BeginInvokeOnMainThread(() =>
{
valuesLock.EnterWriteLock();
try
{
MyCollection[idreference].UploadProgress = temp;
// this value is being bound to Progress property of ProgressBar
}
finally { valuesLock.ExitWriteLock(); }
});
}
also tried:
double temp = Convert.ToDouble((double)e.BytesSent / filesize, CultureInfo.InvariantCulture);
using this, I can obtain the correct result but decimal place separator is ',' not '.'
Upvotes: 0
Views: 624
Reputation: 89092
an int
divided by an int
will return an int
. You need to cast one of the values to a double
first, then the division will return a double
. The Convert
is not needed
double temp = ((double)e.BytesSent) / filesize;
Upvotes: 1
Reputation: 10346
Everything is working but I noticed that ProgressBar goes directly from 0 to 1, it seems not have a smoothly update
If you want to Progressbar update smoothly, I suggest you can use JimBobBennett.AnimatedProgress to implement animation.
Firstly, install JimBobBennett.AnimatedProgress by nuget package, then reference this dll in xaml.
Then use this Attached Properties for ProgressBar.
<ProgressBar
jbb:AttachedProperties.AnimatedProgress="{Binding Source={x:Reference entry1}, Path=Text}"
jbb:AttachedProperties.AnimatedProgressAnimationTime="1000"
jbb:AttachedProperties.AnimatedProgressEasing="BounceOut"
ProgressColor="Red" />
<Entry x:Name="entry1" />
The screenshot:
please take a look Attached Properties:
public static class AttachedProperties
{
public static BindableProperty AnimatedProgressProperty =
BindableProperty.CreateAttached("AnimatedProgress",
typeof(double),
typeof(ProgressBar),
0.0d,
BindingMode.OneWay,
propertyChanged: (b, o, n) => ProgressBarProgressChanged((ProgressBar)b, (double)n));
public static BindableProperty AnimatedProgressAnimationTimeProperty =
BindableProperty.CreateAttached("AnimatedProgressAnimationTime",
typeof(int),
typeof(ProgressBar),
800,
BindingMode.OneWay);
public static BindableProperty AnimatedProgressEasingProperty =
BindableProperty.CreateAttached("AnimatedProgressEasing",
typeof(string),
typeof(ProgressBar),
default(string),
BindingMode.OneWay);
public static double GetAnimatedProgress(BindableObject target) => (double)target.GetValue(AnimatedProgressProperty);
public static void SetAnimatedProgress(BindableObject target, double value) => target.SetValue(AnimatedProgressProperty, value);
public static int GetAnimatedProgressAnimationTime(BindableObject target) => (int)target.GetValue(AnimatedProgressAnimationTimeProperty);
public static void SetAnimatedProgressAnimationTime(BindableObject target, int value) => target.SetValue(AnimatedProgressAnimationTimeProperty, value);
public static string GetAnimatedProgressEasing(BindableObject target) => (string)target.GetValue(AnimatedProgressEasingProperty);
public static void SetAnimatedProgressEasing(BindableObject target, string value) => target.SetValue(AnimatedProgressEasingProperty, value);
private static void ProgressBarProgressChanged(ProgressBar progressBar, double progress)
{
ViewExtensions.CancelAnimations(progressBar);
var animationTime = GetAnimatedProgressAnimationTime(progressBar);
var easingName = GetAnimatedProgressEasing(progressBar);
progressBar.ProgressTo(progress, Convert.ToUInt32(Math.Max(0, animationTime)), GetEasing(easingName));
}
private static Easing GetEasing(string easingName)
{
if (easingName.ToUpper() == nameof(Easing.BounceIn).ToUpper())
return Easing.BounceIn;
if (easingName.ToUpper() == nameof(Easing.BounceOut).ToUpper())
return Easing.BounceOut;
if (easingName.ToUpper() == nameof(Easing.CubicIn).ToUpper())
return Easing.CubicIn;
if (easingName.ToUpper() == nameof(Easing.CubicOut).ToUpper())
return Easing.CubicOut;
if (easingName.ToUpper() == nameof(Easing.CubicInOut).ToUpper())
return Easing.CubicInOut;
if (easingName.ToUpper() == nameof(Easing.Linear).ToUpper())
return Easing.Linear;
if (easingName.ToUpper() == nameof(Easing.SinIn).ToUpper())
return Easing.SinIn;
if (easingName.ToUpper() == nameof(Easing.SinOut).ToUpper())
return Easing.SinOut;
if (easingName.ToUpper() == nameof(Easing.SinInOut).ToUpper())
return Easing.SinInOut;
if (easingName.ToUpper() == nameof(Easing.SpringIn).ToUpper())
return Easing.SpringIn;
if (easingName.ToUpper() == nameof(Easing.SpringOut).ToUpper())
return Easing.SpringOut;
return Easing.SinIn;
}
}
Upvotes: 2