Раскадровка WPF не приостанавливается
-
05-07-2019 - |
Вопрос
У меня есть очень простая раскадровка с Int32Animation, которая нацелена на пользовательский DP в моем классе.
У меня есть обратный вызов OnChanged для моего DP, который выполняет консоль.WriteLine ("Текущее значение:" + MyDP).
Когда я запускаю раскадровку, я могу видеть вывод на консоль просто отлично, и когда я приостанавливаю раскадровку, вывод на консоль прекращается, НО, когда я возобновляю раскадровку, DP НЕ является следующим значением, которое должно быть.Он продолжает увеличиваться, даже несмотря на то, что раскадровка остановлена.
Случалось ли с кем-нибудь что-нибудь подобное?
вот фрагмент кода того, что я делаю
Int32Animation element = new Int32Animation();
element.From = 0;
element.To = targetTo;
element.Duration = dur;
Storyboard.SetTargetProperty(element, new PropertyPath(CurrentFrameProperty));
_filmstripStoryboard = new Storyboard {SpeedRatio = this.FrameRate};
_filmstripStoryboard.Children.Add(element);
public void Start()
{
_filmstripStoryboard.Begin(this, true);
}
public void Pause()
{
_filmstripStoryboard.Pause(this);
}
public void Unpause()
{
_filmstripStoryboard.Resume(this);
}
Решение
Там есть тема на форумах MSDN где Microsoft подтверждает, что такое поведение (текущее значение сохраняется, даже когда раскадровка приостановлена на некоторое время) является ошибкой в текущей на тот момент (по состоянию на 2006 год) версии WPF.Тема форума содержит предлагаемый обходной путь, в частности, сохранение текущей позиции при приостановке и возврат к этой же позиции вручную при возобновлении.
В ветке упоминается, что они думали об исправлении ошибки в будущей версии, но я не знаю, действительно ли .NET 3.5 или 4.0 исправили эту ошибку или нет.
Редактировать: Похоже, что ошибка исправлена в .NET 4.0 - я смог приостановить, а затем возобновить анимацию без перескакивания вперед за прошедшее время.(Я не тестировал в версии 3.5.)
Другие советы
Теперь в версии 4.0 нет ошибки .Приведенный ниже код работает нормально.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfAnimation.Win1805787"
xmlns:Local="clr-namespace:WpfAnimation"
x:Name="MyWindow"
Title="Win1805787"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBox HorizontalAlignment="Right" VerticalAlignment="Top" Width="75" Text="{Binding CurrentFrame, ElementName=MyWindow}" Height="20" Margin="5,0,5,5"/>
<Button x:Name="Play1" Content="Play" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="Play_Click" Margin="5,0,5,5"/>
<Button x:Name="Pause1" Content="Pause" HorizontalAlignment="Right" VerticalAlignment="Top" Width="75" Click="Pause_Click" Margin="5,0,5,5"/>
<Button x:Name="Resume1" Content="Resume" HorizontalAlignment="Right" VerticalAlignment="Top" Width="75" Click="Resume_Click" Margin="5,0,5,5"/>
</StackPanel>
</Grid>
</Window>
/////////////////////////
using System;
using System.Collections.Generic;
using System.Text;
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.Shapes;
using System.Windows.Media.Animation;
namespace WpfAnimation
{
/// <summary>
/// Interaction logic for Win1805787.xaml
/// </summary>
public partial class Win1805787 : Window
{
public Win1805787()
{
this.InitializeComponent();
_createStoryBoard();
// Insert code required on object creation below this point.
}
public int CurrentFrame
{
get { return (int)GetValue(CurrentFrameProperty); }
set { SetValue(CurrentFrameProperty, value); }
}
// Using a DependencyProperty as the backing store for CurrentFrame. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CurrentFrameProperty =
DependencyProperty.Register("CurrentFrame", typeof(int), typeof(Win1805787),
new PropertyMetadata(0, new PropertyChangedCallback(OnValueChanged)));
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
Storyboard _filmstripStoryboard;
void _createStoryBoard()
{
Int32Animation element = new Int32Animation();
element.From = 0;
element.To = 100;
element.Duration = Duration.Plus(new Duration(new TimeSpan(1000000000)));
Storyboard.SetTargetProperty(element, new PropertyPath(CurrentFrameProperty));
_filmstripStoryboard = new Storyboard { SpeedRatio = 0.5 };
_filmstripStoryboard.Children.Add(element);
}
private void Play_Click(object sender, System.Windows.RoutedEventArgs e)
{
_filmstripStoryboard.Begin(this, true);
}
private void Pause_Click(object sender, System.Windows.RoutedEventArgs e)
{
_filmstripStoryboard.Pause(this);
}
private void Resume_Click(object sender, System.Windows.RoutedEventArgs e)
{
_filmstripStoryboard.Resume(this);
}
}
}