2011-06-01 3 views
2

У меня есть DoubleAnimation, что я хочу связать свои свойства From, To и Duration, чтобы они плавно менялись.Свойство Binding the Duration анимации в Silverlight

Связывание From и To отлично работает, плавно меняет их, но изменения Длительности просто игнорируются.

Для отладки я сделал кнопку, которая нажимает на вызовы методов Stop и Begin, содержащих StoryBoard, и анимация начинается с начала с правильной продолжительностью. Также я проверил и увидел, что свойство Duration анимации фактически обновляется каждый раз, поэтому изменение просто игнорируется анимацией. (В отличие от С и К, которые действительно реагируют гладко.)

Пробовал то же самое в WPF и получил те же результаты, вот фрагмент кода:

 <Canvas> 
     <Canvas.Triggers> 
      <EventTrigger RoutedEvent="Canvas.Loaded"> 
       <BeginStoryboard> 
        <Storyboard x:Name="Story"> 
         <DoubleAnimation x:Name="Anime" 
             Duration="{Binding Duration}" 
             RepeatBehavior="Forever" 
             Storyboard.TargetName="Text1" 
             Storyboard.TargetProperty="(Canvas.Left)"            
             From="0" 
             To="400"            
             /> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger> 
     </Canvas.Triggers> 
     <TextBlock Text="Hello" Name="Text1"/> 
    </Canvas> 

Я был бы очень признателен объяснение, почему это не рабочая и любые обходные пути, которые сделают обязательную работу с плавным переходом.

Кроме того, фактическая конечная цель состоит в том, чтобы TextBlock двигался с постоянной скоростью, несмотря на изменения в From и To. Поэтому, если есть другой способ достичь этого, это будет еще лучше.

Спасибо.

ответ

1

Существует две проблемы: как ваш источник привязки (ViewModel) написан, и вы обновили свой datacontext. Вот мой код, и он работает.

MainPage.xaml:

<Canvas> 
    <Canvas.Triggers> 
     <EventTrigger RoutedEvent="Canvas.Loaded"> 
      <BeginStoryboard> 
       <Storyboard x:Name="Story"> 
        <DoubleAnimation x:Name="Anime" 
            Duration="{Binding}" 
            RepeatBehavior="Forever" 
            Storyboard.TargetName="Text1" 
            Storyboard.TargetProperty="(Canvas.Left)"            
            From="0" 
            To="400"            
            /> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
    </Canvas.Triggers> 
    <TextBlock Text="Hello" Name="Text1"/> 
    <Button Content="Change" Margin="0, 100, 0, 0" Click="Button_Click" /> 
</Canvas> 

в MainPage.xaml.cs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 
using System.ComponentModel; 

namespace SilverlightApplication 
{ 
    public partial class MainPage : UserControl 
    { 
     AnimVM vm = new AnimVM(); 
     double dur = 5; 

     public MainPage() 
     { 
      InitializeComponent(); 

      vm.Duration = new Duration(TimeSpan.FromSeconds(dur)); 

      this.DataContext = vm.Duration; 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      dur += 5; 
      vm.Duration = new Duration(TimeSpan.FromSeconds(dur)); 
      this.DataContext = vm.Duration; // don't forget this line 
     } 
    } 

    public class ViewModelBase : INotifyPropertyChanged, IDisposable 
    { 
     protected ViewModelBase() 
     { 
     } 

     protected virtual bool ThrowOnInvalidPropertyName { get; private set; } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged(string propertyName) 
     { 
      //this.VerifyPropertyName(propertyName); 

      PropertyChangedEventHandler handler = this.PropertyChanged; 
      if (handler != null) 
      { 
       var e = new PropertyChangedEventArgs(propertyName); 
       handler(this, e); 
      } 
     } 

     public void Dispose() 
     { 
      this.OnDispose(); 
     } 

     protected virtual void OnDispose() 
     { 
     } 
    } 

    public class AnimVM : ViewModelBase 
    { 
     private Duration _duration = new Duration(TimeSpan.FromSeconds(5)); 
     public Duration Duration 
     { 
      get { return _duration; } 
      set 
      { 
       if (object.ReferenceEquals(this._duration, value)) return; 

       this._duration = value; 
       base.OnPropertyChanged("Duration"); 
      } 
     } 
    } 
} 
+0

Как я уже говорил, насколько я могу заняться связями, я изменил и продолжил мой вариант в моей модели, а свойство duration анимации было обновлено немедленно каждый раз, просто мне нужно было вызвать StoryBoard.Stop , StoryBoard.Begin, чтобы анимация действительно изменилась. Можете ли вы показать мне свой XAML? – Evgeny

+0

Вот xaml и .cs, вы можете нажать кнопку, чтобы изменить продолжительность. – demaxSH

0

Я знаю, что путь поздно к партии, но проблема в том, что Duration не является DependencyProperty, поэтому WPF не слушает событие изменения значения, и поэтому не u pdating анимация при изменении значения - это отличается от того, как просто сохранить обновленное значение в объекте.