我有一个wpf应用程序,其中矩形在10秒内在一秒钟内在红色和黑色之间改变颜色。我想要的是能够在经过毫秒达到6秒(6000毫秒)时更快地改变颜色。
我(大多数情况下)工作,但问题是它在2秒标记后切换太快。我希望它会在接近最后几秒时变得更快。
这是我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Timers;
using System.Diagnostics;
namespace Test
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Grid_Loaded(object sender, RoutedEventArgs e)
{
SoftBlink(6000); //6 seconds...
}
private async void SoftBlink(short CycleTime_ms)
{
Stopwatch sw = new Stopwatch(); sw.Start();
int interval = 500;
while (sw.ElapsedMilliseconds < CycleTime_ms)
{
await Task.Delay(interval);
recTest.Fill = Brushes.Red;
await Task.Delay(interval);
recTest.Fill = Brushes.Black;
interval -= (int)(interval * 0.5);
}
sw.Stop();
}
}
}
有人能看出我做错了吗?
答案 0 :(得分:0)
这种类型的动画需要用故事板完成;用任务await操纵颜色不会真正给出预期的结果。
这与Storyboard动画相当直接。您将需要使用具有PowerEase功能的ColorAnimation,这将允许您逐渐增加或减少动画速度/过渡。
这是一个简单的例子,点击按钮将改变矩形的填充颜色。它将运行故事板6秒。动画是0.5秒长,但故事板将在代码中反复重复,直到我们达到6秒。在每次迭代中,我们将增加Power属性以加速颜色转换。
操纵powerFactor值以查看效果如何。您也可以使用EasingMode
<强>的Xaml 强>
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Storyboard x:Key="Storyboard1">
<ColorAnimationUsingKeyFrames x:Name="Animation" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Flash">
<EasingColorKeyFrame KeyTime="0" Value="Red"/>
<EasingColorKeyFrame KeyTime="0:0:0.5" Value="Black">
<EasingColorKeyFrame.EasingFunction>
<PowerEase EasingMode="EaseInOut"/>
</EasingColorKeyFrame.EasingFunction>
</EasingColorKeyFrame>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Grid Background="Gray">
<Rectangle x:Name="Flash" Height="100" Width="100" Fill="Red">
</Rectangle>
<Button x:Name="button" Content="Button" Margin="246,0,196,34.04" VerticalAlignment="Bottom" Click="button_Click"/>
</Grid>
</Window>
代码
public partial class MainWindow : Window
{
private Stopwatch timer = new Stopwatch();
private static readonly double powerFactor = .3;
private Storyboard storyboard;
private PowerEase easingFunction;
public MainWindow()
{
InitializeComponent();
//handle the completed event to re-execute the storyboard
this.storyboard = this.Resources["Storyboard1"] as Storyboard;
this.storyboard.Completed += Storyboard_Completed;
//get the animation to locate our easing function defined in xaml.
var animation = storyboard.Children[0] as ColorAnimationUsingKeyFrames;
//find the second keyframe, thats the one that has easing function.
this.easingFunction = (animation.KeyFrames[1] as EasingColorKeyFrame).EasingFunction as PowerEase;
}
private void button_Click(object sender, RoutedEventArgs e)
{
this.timer.Reset();
this.timer.Start();
this.easingFunction.Power = 0;
RunStoryboard();
}
private void Storyboard_Completed(object sender, EventArgs e)
{
if (timer.ElapsedMilliseconds < 6000)
{
RunStoryboard();
}
}
private void RunStoryboard()
{
this.easingFunction.Power += powerFactor;
storyboard.Begin();
}
}