Xamarin ProgressBar 绑定进度
Xamarin ProgressBar binding Progress
我的 ProgressBar 的进度 属性 由名为 UploadProgressCallback 的方法更新,由 UploadProgressChanged 事件调用。一切正常,但我注意到 ProgressBar 直接从 0 变为 1,它似乎没有顺利更新,我决定分析操作输出并意识到发送字节除以文件大小被截断为 0,所以一些结果应该是 0.234 或 0.643,进入 Progress 属性 为“0”,这会导致 bar 一直停留在初始点,当上传完成时,除法将明显 return 1 并且 bar 被填充。我尝试了很多方法,但输出始终为 0。有没有人有解决此问题的建议?
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(); }
});
}
也尝试过:
double temp = Convert.ToDouble((double)e.BytesSent / filesize, CultureInfo.InvariantCulture);
使用这个,我可以获得正确的结果,但小数点分隔符是“,”而不是“.”
Everything is working but I noticed that ProgressBar goes directly from 0 to 1, it seems not have a smoothly update
如果你想让Progressbar更新的更流畅,建议你可以使用JimBobBennett.AnimatedProgress来实现动画。
首先,通过nuget包安装JimBobBennett.AnimatedProgress,然后在xaml.
中引用这个dll
然后将此附加属性用于 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" />
截图:
请查看附加属性:
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;
}
}
一个int
除以一个int
将return一个int
。您需要先将其中一个值转换为 double
,然后除法将 return 转换为 double
。 Convert
不需要
double temp = ((double)e.BytesSent) / filesize;
我的 ProgressBar 的进度 属性 由名为 UploadProgressCallback 的方法更新,由 UploadProgressChanged 事件调用。一切正常,但我注意到 ProgressBar 直接从 0 变为 1,它似乎没有顺利更新,我决定分析操作输出并意识到发送字节除以文件大小被截断为 0,所以一些结果应该是 0.234 或 0.643,进入 Progress 属性 为“0”,这会导致 bar 一直停留在初始点,当上传完成时,除法将明显 return 1 并且 bar 被填充。我尝试了很多方法,但输出始终为 0。有没有人有解决此问题的建议?
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(); }
});
}
也尝试过:
double temp = Convert.ToDouble((double)e.BytesSent / filesize, CultureInfo.InvariantCulture);
使用这个,我可以获得正确的结果,但小数点分隔符是“,”而不是“.”
Everything is working but I noticed that ProgressBar goes directly from 0 to 1, it seems not have a smoothly update
如果你想让Progressbar更新的更流畅,建议你可以使用JimBobBennett.AnimatedProgress来实现动画。
首先,通过nuget包安装JimBobBennett.AnimatedProgress,然后在xaml.
中引用这个dll然后将此附加属性用于 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" />
截图:
请查看附加属性:
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;
}
}
一个int
除以一个int
将return一个int
。您需要先将其中一个值转换为 double
,然后除法将 return 转换为 double
。 Convert
不需要
double temp = ((double)e.BytesSent) / filesize;