我正在开发一个 MVVM 应用程序,我希望有一个 ProgressBar,当该属性发生变化时,它可以平滑地为它的新值设置动画。我已经使用 c# 看到了这个问题的几个答案,但我更愿意在模板中完成所有这些。我遇到的问题是正确设置和定位事件和 Storyboard。这是我目前拥有的:
进度条-
样式-(只是触发器)
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="RangeBase.ValueChanged">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="???????"
Storyboard.TargetProperty="Value"
To="???????" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
我从这里获取了触发代码:http://msdn.microsoft.com/en-us/library/system.windows.controls.progressbar(v=vs.110).aspx .
如何将 TargetName 设置为模板本身,以便它应用于使用该模板的所有控件?如何将“To”设置为传入值?似乎有一种方法可以获取“绑定(bind)”值,但我将 Value 和 Max 都绑定(bind)到进度条元素上。它怎么知道要使用什么?
这里是整个模板供引用:
<Style x:Key="ProgressStyle" TargetType="{x:Type ProgressBar}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid MinHeight="14" MinWidth="20">
<Border x:Name="BaseRectangle" Background="{StaticResource BaseColor}" CornerRadius="10,0,10,0"></Border>
<Border x:Name="GlassRectangle" CornerRadius="10,0,10,0" Background="{StaticResource GlassFX}" Panel.ZIndex="10"></Border>
<Border x:Name="animation" CornerRadius="10,0,10,0" Opacity=".7" Background="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Left"></Border>
<Border x:Name="PART_Indicator" CornerRadius="10,0,10,0" Background="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Left"></Border>
<Border x:Name="PART_Track" BorderThickness="1" CornerRadius="10,0,10,0" BorderBrush="Black"></Border>
<Border x:Name="BordeCabeceraSombra" BorderThickness="2" CornerRadius="10,0,10,0" BorderBrush="DarkGray" Opacity=".2" Margin="1,1,1,0"></Border>
<Label x:Name="Progress" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontWeight="Bold" Foreground="White" Opacity=".7" Content="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}}"></Label>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="RangeBase.ValueChanged">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="???????"
Storyboard.TargetProperty="Value"
From="???????" To="???????" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<Trigger Property="IsIndeterminate" Value="True">
<Setter Property="Visibility" TargetName="Progress" Value="Hidden"></Setter>
<Setter Property="Background" TargetName="PART_Indicator">
<Setter.Value>
<MultiBinding>
<MultiBinding.Converter>
<wintheme:ProgressBarHighlightConverter/>
</MultiBinding.Converter>
<Binding Source="{StaticResource GlowFXProgressAnimated}"/>
<Binding Path="ActualWidth" ElementName="BaseRectangle"/>
<Binding Path="ActualHeight" ElementName="BaseRectangle"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value=".5"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
如有任何帮助,我们将不胜感激!
最佳答案
我认为这是更好的方法。
您可以创建行为来执行此操作。 (MVVM WPF)
创建类:
class ProgresBarAnimateBehavior : Behavior<ProgressBar>
{
bool _IsAnimating = false;
protected override void OnAttached()
{
base.OnAttached();
ProgressBar progressBar = this.AssociatedObject;
progressBar.ValueChanged += ProgressBar_ValueChanged;
}
private void ProgressBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (_IsAnimating)
return;
_IsAnimating = true;
DoubleAnimation doubleAnimation = new DoubleAnimation
(e.OldValue, e.NewValue, new Duration(TimeSpan.FromSeconds(0.3)), FillBehavior.Stop);
doubleAnimation.Completed += Db_Completed;
((ProgressBar)sender).BeginAnimation(ProgressBar.ValueProperty, doubleAnimation);
e.Handled = true;
}
private void Db_Completed(object sender, EventArgs e)
{
_IsAnimating = false;
}
protected override void OnDetaching()
{
base.OnDetaching();
ProgressBar progressBar = this.AssociatedObject;
progressBar.ValueChanged -= ProgressBar_ValueChanged;
}
}
简单的用法:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:b="clr-namespace:YOURNAMESPACE.Behaviors"
<ProgressBar Height="7"
Value="{Binding LoadingValue}">
<i:Interaction.Behaviors>
<b:ProgresBarAnimateBehavior />
</i:Interaction.Behaviors>
</ProgressBar>
关于c# - WPF 模板中的平滑动画 ProgressBar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26618308/