我正在尝试创建一个ProgressBar
,它可以从0动画到某个值。大部分时间一切都很好...
我正在使用Owen Johnson中的代码。进行如下更改:
public static readonly DependencyProperty SmoothValueProperty =
DependencyProperty.RegisterAttached("SmoothValue", typeof(double), typeof(ProgressBarSmoother),
new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, changing, coerceValueCallback, false, System.Windows.Data.UpdateSourceTrigger.PropertyChanged));
private static object coerceValueCallback(DependencyObject d, object baseValue)
{
Console.WriteLine($"{ (double)baseValue } coercevalue");
return baseValue;
}
public static void changing(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ProgressBarSmoother obj = d as ProgressBarSmoother;
Console.WriteLine($"Contador: {++obj.Count}. Valor novo: { e.NewValue }");
if ((double)e.NewValue == 0)
{
obj.ResetAnimation();
Console.WriteLine($"Contador: {++obj.Count}");
obj.Value = 0;
return;
}
obj.Animation = new DoubleAnimation(0d, (double)e.NewValue, TimeSpan.FromMilliseconds((double)e.NewValue));
obj.Animation.Completed += (sender, arg) =>
{
obj.Animation = null;
obj.Value = 0;
obj.BeginAnimation(ValueProperty, null, HandoffBehavior.SnapshotAndReplace);
Console.WriteLine("Animation completed");
};
obj.Foreground = new SolidColorBrush(Colors.Red);
obj.BeginAnimation(ValueProperty, obj.Animation, HandoffBehavior.SnapshotAndReplace);
Console.WriteLine($"Contador: {++obj.Count}");
}
// Basically the code that changes the progressbar value is this
private void Controller_OnPlayerChangedState(object sender, MultiPlayerController.OnChangeStateEventArgs e)
{
if (e.NewState == AudioPlayer_State.Playing)
{
Duration = AudioPanel.Controller.GetDuration();
panel.SetCurrentPositionAsync (Duration);
}
else if(e.NewState != AudioPlayer_State.Playing && e.NewState != AudioPlayer_State.Paused)
{
panel.SetCurrentPositionAsync ((long)0);
//System.Threading.Thread.Sleep(100);
}
}
(有很多代码仅供测试,看看有什么令人高兴的地方)
我有一个音频播放器,progressbar
是要查看音频的实际位置(不能暂停,只能停止)。停止按钮可以正常工作。问题是当“重复”状态被激活时。
我从dll中收到一个事件Stopped(将值设置为0,动画消失了),过了一会儿(大多数时间少于0ms),正在播放,所以我必须用{持续时间。
有时我的动画没有被调用,我放了一些日志来发现白色。不调用时,progressbar
仅发生一次。当工作时,调用两次:一次为0,当我销毁较早的动画时,另一次以新的持续时间(与以前相同)。
仅出于测试目的,我在代码中放入了CoerceValueCallback
,它将值更改为新的持续时间,并且像一个超级按钮一样工作。我的想法是更改新值的延迟...基本上,我需要先设置为0,然后再设置为新值。
我可以删除较旧的支票需要与新的支票不同吗?或者我可以立即更新该值?
我在控件Thread.Sleep
上创建了名为ProgressBarSmoother
的公用函数
ResetAnimation
并创建了public void ResetAnimation()
{
this.Dispatcher.Invoke(() =>
{
SmoothValue = 0;
});
}
的{{1}}
getter/setter
在我的SmoothValue
上
public double SmoothValue
{
get => (double)GetValue(SmoothValueProperty);
set => SetValue(SmoothValueProperty, value);
}
我的改变
SetCurrentPositionAsync
所以..当我设置为0时,我立即调用public void SetCurrentPositionAsync (long position)
{
if (position == 0)
progressBar.ResetAnimation();
CurrentPositionAsync = position;
}
,它可以设置属性的值并正确设置字段,而不是调用public static void changing(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ProgressBarSmoother obj = d as ProgressBarSmoother;
if ((double)e.NewValue == 0)
{
obj.BeginAnimation(ValueProperty, null, HandoffBehavior.SnapshotAndReplace);
return;
}
obj.Animation = new DoubleAnimation(0d, (double)e.NewValue, TimeSpan.FromMilliseconds((double)e.NewValue));
obj.BeginAnimation(ValueProperty, obj.Animation, HandoffBehavior.SnapshotAndReplace);
}
并有一些延迟。
我的ResetAnimation
:
OnPropertyChanged
工作正常,但我不知道是否可以有其他解决方案。