-1

我对 WPF 动画比较陌生。我想让一个对象(例如一个简单的圆圈)以 10 度的增量围绕圆形路径移动。以下示例非常接近: WPF 圆形移动对象 请参阅 Clemens 的答案,他在 XAML 中使用 RotateTransform 并在代码隐藏中使用 DoubleAnimation。但是,我正在使用 MVVM,但我不清楚如何实现这一点。我相信我需要从我的 ViewModel 访问视图中的 RotateTransform,所以我可以调用 BeginAnimation,但是如何调用呢?

有什么例子或想法吗?我没有运气搜索过。谢谢

更新:我现在可以通过展示我已经尝试过的内容来更具体地说明我的问题。基于上述参考和双向绑定视图的 DependencyProperty 到视图模型的属性?(@Michael Schnerring 回答),我有以下简单代码(如下)。我的椭圆没有旋转。没有装订错误或任何其他错误,只是没有旋转。我的方法被击中(我调试了它)我猜我的 PerformAnimation 函数不正确,特别是 SetTargetProperty 部分。我确实尝试通过添加两个动画(一个用于旋转,一个用于变换)来玩它,但没有运气。

有人可以告诉我我做错了什么吗?

XAML:

<Canvas Grid.Row="0" Grid.Column="0">
        <Ellipse Height="100" Width="100" Fill="Aqua" Name="MyEllipse"
         Canvas.Left="200" Canvas.Top="200"
         RenderTransformOrigin="0.5,0.5">
            <Ellipse.RenderTransform>
                <TransformGroup>
                    <TranslateTransform Y="-100"/>
                <RotateTransform />
                </TransformGroup>
            </Ellipse.RenderTransform>
        </Ellipse>
    </Canvas>

    <Button Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Command="{Binding Path=RotateCommand}">Press Me!</Button>

代码隐藏

  public partial class MainWindow : Window
   {
      public MainWindow()
      {
         InitializeComponent();
         var nameOfPropertyInVm = "AngleProperty";
    var binding = new Binding(nameOfPropertyInVm) { Mode = BindingMode.TwoWay };
         this.SetBinding(AngleProperty, binding);
      }

      public double Angle
      {
         get { return (double)GetValue(AngleProperty); }
         set { SetValue(AngleProperty, value); }
      }

      // Using a DependencyProperty as the backing store for Angle.  This enables animation, styling, binding, etc...
      public static readonly DependencyProperty AngleProperty = DependencyProperty.Register("Angle", typeof(double), typeof(MainWindow), new UIPropertyMetadata(0.0, new PropertyChangedCallback(AngleChanged)));

      private static void AngleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
      {
         MainWindow control = (MainWindow)sender;
         control.PerformAnimation((double)e.OldValue, (double)e.NewValue);
      }

      private void PerformAnimation(double oldValue, double newValue)
      {
         Storyboard s = new Storyboard();

         DoubleAnimation animation = new DoubleAnimation();
         animation.From = oldValue;
         animation.To = newValue;
         animation.Duration = new Duration(TimeSpan.FromSeconds(1));
         s.Children.Add(animation);

         
         Storyboard.SetTarget(animation, MyEllipse);
         Storyboard.SetTargetProperty(animation, new PropertyPath("(Ellipse.RenderTransform).(RotateTransform.Angle)"));

         s.Begin();

      }

和视图模型

    public class MyViewModel :  ViewModelBase
   {
      private ICommand _rotateCommand = null;
      private double _angleProperty = 10;
      public MyViewModel()
      {
         
      }

      public double AngleProperty
      {
         get
         {
            return _angleProperty;
         }

         set
         {
            _angleProperty = value;
            OnPropertyChanged("AngleProperty");
         }
      }

      public ICommand RotateCommand
      {
         get
         {
            if (_rotateCommand == null)
            {
               _rotateCommand = new RelayCommand(param => RotateCommandImplementation());
            }
            return _rotateCommand;
         }
      }

      private void RotateCommandImplementation()
      {
         AngleProperty = AngleProperty + 10;
      }
   }
4

1 回答 1

0

这是我的解决方案,基于@Clemens 的大量帮助(请参阅评论和WPF 圆形移动对象

看法

<Window x:Class="AnimationBindingPlay.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:AnimationBindingPlay"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Canvas Grid.Row="0" Grid.Column="0">
        <Ellipse Height="100" Width="100" Fill="Aqua" Name="MyEllipse"
         Canvas.Left="200" Canvas.Top="200"
         RenderTransformOrigin="0.5,0.5">
            <Ellipse.RenderTransform>
                <TransformGroup>
                    <TranslateTransform Y="-100"/>
                    <RotateTransform x:Name="rotateTransform"/>
                </TransformGroup>
            </Ellipse.RenderTransform>
        </Ellipse>
    </Canvas>

    <Button Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Command="{Binding Path=RotateCommand}">Press Me!</Button>
    
</Grid>

背后的代码

 public partial class MainWindow : Window
   {
      public MainWindow()
      {
         InitializeComponent();
         var nameOfPropertyInVm = "AngleProperty";
         var binding = new Binding(nameOfPropertyInVm) { Mode = BindingMode.TwoWay };
         this.SetBinding(AngleProperty, binding);
      }

      public double Angle
      {
         get { return (double)GetValue(AngleProperty); }
         set { SetValue(AngleProperty, value); }
      }

      // Using a DependencyProperty as the backing store for Angle.  This enables animation, styling, binding, etc...
      public static readonly DependencyProperty AngleProperty = DependencyProperty.Register("Angle", typeof(double), typeof(MainWindow), new UIPropertyMetadata(0.0, new PropertyChangedCallback(AngleChanged)));

      private static void AngleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
      {
         MainWindow control = (MainWindow)sender;
         control.PerformAnimation((double)e.OldValue, (double)e.NewValue);
      }

      private void PerformAnimation(double oldValue, double newValue)
      {
       
         var rotationAnimation = new DoubleAnimation(oldValue, newValue, TimeSpan.FromSeconds(1));
         rotateTransform.BeginAnimation(RotateTransform.AngleProperty, rotationAnimation);

      }

   }

ViewModel 与问题相同!

于 2022-02-03T00:07:10.227 回答