2012-05-10 37 views
0

我需要創建一個動畫,當用戶滾動時,然後按鈕左右動畫根據滾動的方向。我需要對這個動畫有很多控制權,因爲用戶可以在動畫發生的同時滾動。因此我決定創建我自己的動畫而不使用故事板。這是我做的創建我的動畫:爲什麼創建非故事板動畫不光滑

項目類

class Item : INotifyPropertyChanged 
{ 
    Thickness _M; 
    public Thickness M 
    { 
     get 
     { 
      return _M; 
     } 
     set 
     { 
      _M = value; 
      OnPropertyChanged("M"); 
     } 
    } 

    // properties needed to animate the control 
    public double MarginLeft 
    { 
     get 
     { 
      return _M.Left; 
     } 
     set 
     { 
      _M.Left = value; 
      OnPropertyChanged("M"); 
     } 
    } 

    // implement INotifyPropertyChanged interface 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    // the control that we will be animating 
    public Button Btn { get; set; } 

    //Constructor that takes care of initializing the button and then setting 
    // a binding so that we could update the button's position on separate threads 
    public Item() 
    { 
     Binding b = new Binding("M") 
     { 
      Source = this 
     }; 

     Btn = new Button() 
     { 
      HorizontalAlignment = HorizontalAlignment.Left, 
      VerticalAlignment = VerticalAlignment.Top, 
      Width = 100, 
      Height = 30   
     }; 

     Btn.SetBinding(Button.MarginProperty, b); 

    } 


    double x = 0; 
    volatile int threadCounter = 0; 
    object _rightLock = new object(); 

    // method to animate the button 
    public void MoveHorizontaly(double speed) 
    { 
     x += speed; 
     threadCounter++; 

     Task.Factory.StartNew(() => 
     { 
      lock (_rightLock) 
      { 
       while (Math.Abs(x) > .3) 
       { 
        MarginLeft += x; 
        x *= .97; 
        Thread.Sleep(2); 
        if (threadCounter > 1) // if a new animation will take place exit from this one 
         break; 
       } 

       threadCounter--; 
      } 
     }); 
    } 

} 

主窗口XAML:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" PreviewMouseWheel="Window_PreviewMouseWheel"> 
    <Grid> 
     <Grid Height="241" Margin="12,58,12,0" Name="grid1" VerticalAlignment="Top" Background="#FFFF9999"></Grid> 
    </Grid> 
</Window> 

主窗口後面的代碼:

public partial class MainWindow : Window 
{ 

    Item item1 = new Item(); 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     grid1.Children.Add(item1.Btn); 
    } 

    // event that fires when user scrolls on the main window 
    private void Window_PreviewMouseWheel(object sender, MouseWheelEventArgs e) 
    { 
     item1.MoveHorizontaly(e.Delta/50); 
    } 


} 

如何我可以改進這個動畫嗎?它不是那麼糟糕,但在故事板上創建的動畫更加流暢...

回答

1

看起來有點像做動畫的複雜方式。像這樣的東西會更好嗎?

的Xaml

<Window x:Class="WpfApplication1.MainWindow" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:app="clr-namespace:WpfApplication1" 
      Title="MainWindow" Height="350" Width="525" PreviewMouseWheel="Window_PreviewMouseWheel"> 
     <Grid> 
      <Grid Height="241" Margin="12,58,12,0" Name="grid1" VerticalAlignment="Top" Background="#FFFF9999"> 
       <Button Content="Test" Height="20" Width="60"> 
        <Button.RenderTransform> 
         <TranslateTransform x:Name="_transform" /> 
        </Button.RenderTransform> 
       </Button> 
      </Grid> 
     </Grid> 
    </Window> 

代碼後面

public partial class MainWindow : Window 
{ 
    DoubleAnimation _animation; 

    public MainWindow() 
    { 
     InitializeComponent(); 
     _animation = new DoubleAnimation(); 
     _animation.Duration = new Duration(TimeSpan.FromMilliseconds(150)); 
     _animation.FillBehavior = FillBehavior.HoldEnd; 
    } 

    private void Window_PreviewMouseWheel(object sender, MouseWheelEventArgs e) 
    { 
     double x = _transform.X; 
     _transform.BeginAnimation(TranslateTransform.XProperty, null); 
     _transform.SetValue(TranslateTransform.XProperty, x); 

     _animation.To = _transform.X + (e.Delta/2); 
     _transform.BeginAnimation(TranslateTransform.XProperty, _animation); 
    } 
}