2009-03-28 4 views
9

Я использую DoubleAnimation для анонимности свойства Angle для RotationTransform. Несколько раз в секунду мне нужно изменить скорость вращения в ответ на внешние данные, чтобы скорость вращения повышалась и/или замедлялась (плавно) с течением времени. Я сейчас делаю это с помощью DoubleAnimation, который повторяет навсегда от 0.0 до 360,0 с длительностью X, затем несколько раз в секунду:Динамическое изменение анимации вращения в WPF

  • Grab новое значение из внешних данных
  • Изменение скорости на DoubleAnimation к тому, что значение
  • Re-Нанести DoubleAnimation свойству Angle снова

Примечание: Я считаю, что я должен был изменить и из свойств по анимации на «текущий угол» и «текущий угол + 360» - мне повезло, что RotationTransform не имеет проблем с углами > 360 градусов - чтобы предотвратить повторное начало вращения с нулевого угла.

Мой вопрос: это разумно? Это не похоже. Непрерывное применение новых свойств DoubleAnimations к Angle на преобразовании вращения кажется неправильным - вроде как я позволяю WPF оживлять вращение, а I am анимирует скорость вращения самостоятельно.

Есть ли лучший способ?

ответ

8

На раскадровке установлена ​​установка SpeedRatio, которая является мультипликатором продолжительности. Вы не можете привязываться к этому, так как это не свойство зависимостей.

Чтобы обойти это, вы можете использовать функцию SetSpeedRatio на раскадровке. Обратите внимание, что это работает только в том случае, если панель истории запущена в коде (иначе вы получите сообщение об ошибке).

Код, приведенный ниже, представляет собой полный пример того, как вы могли бы возбуждать событие в объекте, чтобы влиять на скорость анимации вращающегося прямоугольника. Цель текстового поля и привязки данных - обновить фоновый объект. Кнопка просто так, что текстовое поле теряет фокус и обновляет объект.

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel> 
     <Rectangle Margin="50" Width="50" Height="50" Fill="Red" x:Name="rc"> 
     <Rectangle.RenderTransform> 
      <RotateTransform x:Name="TransRotate" 
          CenterX="25" CenterY="25" Angle="0" /> 
     </Rectangle.RenderTransform> 
     <Rectangle.Resources> 
      <Storyboard x:Key="spin"> 
      <DoubleAnimation x:Name="da" 
          Storyboard.TargetName="TransRotate" 
          Storyboard.TargetProperty="Angle" 
          By="360" 
          Duration="0:0:10" 
          AutoReverse="False" 
          RepeatBehavior="Forever" /> 
      </Storyboard> 
     </Rectangle.Resources> 
     </Rectangle> 
     <TextBox Text="{Binding Speed}" /> 
     <Button>Update Speed</Button> 
    </StackPanel> 
</Window> 

Тогда C# код

{ 
    public Window1() 
    { 
     InitializeComponent(); 

     //create new object 
     BackgroundObject bo = new BackgroundObject(); 

     //binding only needed for the text box to change speed value 
     this.DataContext = bo; 

     //Hook up event 
     bo.SpeedChanged += bo_SpeedChanged; 

     //Needed to prevent an error 
     Storyboard sb = (Storyboard)rc.FindResource("spin"); 
     sb.Begin(); 
    } 

    //Change Speed 
    public void bo_SpeedChanged( object sender, int newSpeed) 
    { 
     Storyboard sb = (Storyboard)rc.FindResource("spin"); 
     sb.SetSpeedRatio(newSpeed); 
    } 
} 

public delegate void SpeedChangedEventHandler(object sender, int newSpeed); 

public class BackgroundObject 
{ 
    public BackgroundObject() 
    { 
     _speed = 10; 
    } 

    public event SpeedChangedEventHandler SpeedChanged; 

    private int _speed; 
    public int Speed 
    { 
     get { return _speed; } 
     set { _speed = value; SpeedChanged(this,value); } 
    } 
} 

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

+0

Это было бы очень признательно. – Bill

+1

Спасибо, я смогу использовать это. Забавно, что мы должны сделать вызов метода (SetSpeedRatio), что означает, что я не могу анимировать изменение отношения скорости с другой анимацией, все в Xaml и все; но это выглядит намного правильнее, чем применение новых анимаций все время, чтобы получить эффект. Спасибо. – Bill

+0

Этот ответ был наиболее полезен в нашем случае, но есть одно важное отличие, которое не заставило его работать. по крайней мере, с WPF в WinRT. Метод SetSpeedRatio() ничего не сделал, поэтому мы изменили его на свойство SpeedRatio, и это сделало трюк. –

Смежные вопросы