c# – 使用MVVM的动态视图动画

前端之家收集整理的这篇文章主要介绍了c# – 使用MVVM的动态视图动画前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我一直试图弄清楚如何在viewmodel中的属性更新时有效地触发视图中的动画,其中动画取决于所述属性的值.

我在一个简单的应用程序中使用单个View和viewmodel重新创建了我的问题.这里的目标是使用ColorAnimation转换矩形的颜色变化.作为参考,我一直在使用Josh Smith的MVVM Foundation软件包.

示例项目可以是downloaded here.

总而言之,我想在Color属性更改时为View中的颜色过渡设置动画.

MainWindow.xaml

  1. <Window x:Class="MVVM.ColorAnimation.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ColorAnimation="clr-namespace:MVVM.ColorAnimation" Title="MainWindow" Height="350" Width="525">
  4. <Window.DataContext>
  5. <ColorAnimation:MainWindowviewmodel />
  6. </Window.DataContext>
  7. <Grid>
  8. <Grid.RowDefinitions>
  9. <RowDefinition Height="*" />
  10. <RowDefinition Height="40" />
  11. </Grid.RowDefinitions>
  12.  
  13. <Rectangle Margin="10">
  14. <Rectangle.Fill>
  15. <SolidColorBrush Color="{Binding Color}"/>
  16. </Rectangle.Fill>
  17. </Rectangle>
  18.  
  19. <StackPanel Orientation="Horizontal" Grid.Row="1">
  20. <Button Command="{Binding BlueCommand}" Width="100">Blue</Button>
  21. <Button Command="{Binding GreenCommand}" Width="100">Green</Button>
  22. </StackPanel>
  23. </Grid>
  24. </Window>

MainWindowviewmodel.cs

  1. namespace MVVM.ColorAnimation
  2. {
  3. using System.Windows.Input;
  4. using System.Windows.Media;
  5.  
  6. using MVVM;
  7.  
  8. public class MainWindowviewmodel : ObservableObject
  9. {
  10. private ICommand blueCommand;
  11. private ICommand greenCommand;
  12.  
  13. public ICommand BlueCommand
  14. {
  15. get
  16. {
  17. return this.blueCommand ?? (this.blueCommand = new RelayCommand(this.TurnBlue));
  18. }
  19. }
  20.  
  21. private void TurnBlue()
  22. {
  23. this.Color = Colors.Blue;
  24. }
  25.  
  26. public ICommand GreenCommand
  27. {
  28. get
  29. {
  30. return this.greenCommand ?? (this.greenCommand = new RelayCommand(this.TurnGreen));
  31. }
  32. }
  33.  
  34. private void TurnGreen()
  35. {
  36. this.Color = Colors.Green;
  37. }
  38.  
  39. private Color color = Colors.Red;
  40.  
  41. public Color Color
  42. {
  43. get
  44. {
  45. return this.color;
  46. }
  47.  
  48. set
  49. {
  50. this.color = value;
  51. RaisePropertyChanged("Color");
  52. }
  53. }
  54. }
  55. }

无论如何从View中触发ColorAnimation而不是值之间的即时转换?我目前这样做的方式是另一个应用程序非常混乱,因为我通过viewmodel属性设置viewmodel,然后使用PropertyObserver监视值更改,然后创建动画并从代码隐藏中触发它:

  1. this.colorObserver = new PropertyObserver<Player>(value)
  2. .RegisterHandler(n => n.Color,this.CreateColorAnimation);

在我处理许多颜色和许多潜在动画的情况下,这变得非常混乱,并且弄乱了我手动将viewmodel传递给View而不是简单地通过ResourceDictionary绑定两者的事实.我想我也可以在DataContextChanged事件中做到这一点,但是有更好的方法吗?

解决方法

如果只是为了几个动画我会建议使用Visual States.然后,您可以在视图上使用GoToAction行为来触发不同的动画.如果您正在处理许多类似的动画,那么创建自己的行为将是一个更好的解决方案.

更新
我已经创建了一个非常简单的行为来给Rectangle一个小的颜色动画.这是代码.

  1. public class ColorAnimationBehavior : TriggerAction<FrameworkElement>
  2. {
  3. #region Fill color
  4. [Description("The background color of the rectangle")]
  5. public Color FillColor
  6. {
  7. get { return (Color)GetValue(FillColorProperty); }
  8. set { SetValue(FillColorProperty,value); }
  9. }
  10.  
  11. public static readonly DependencyProperty FillColorProperty =
  12. DependencyProperty.Register("FillColor",typeof(Color),typeof(ColorAnimationBehavior),null);
  13. #endregion
  14.  
  15. protected override void Invoke(object parameter)
  16. {
  17. var rect = (Rectangle)AssociatedObject;
  18.  
  19. var sb = new Storyboard();
  20. sb.Children.Add(CreateVisibilityAnimation(rect,new Duration(new TimeSpan(0,1)),FillColor));
  21.  
  22. sb.Begin();
  23. }
  24.  
  25. private static ColorAnimationUsingKeyFrames CreateVisibilityAnimation(DependencyObject element,Duration duration,Color color)
  26. {
  27. var animation = new ColorAnimationUsingKeyFrames();
  28.  
  29. animation.KeyFrames.Add(new SplineColorKeyFrame { KeyTime = new TimeSpan(duration.TimeSpan.Ticks),Value = color });
  30.  
  31. Storyboard.SetTargetProperty(animation,new PropertyPath("(Shape.Fill).(SolidColorBrush.Color)"));
  32. Storyboard.SetTarget(animation,element);
  33.  
  34. return animation;
  35. }
  36.  
  37. }

在xaml中,您只需附加此行为,

  1. <Rectangle x:Name="rectangle" Fill="Black" Margin="203,103,217,227" Stroke="Black">
  2. <i:Interaction.Triggers>
  3. <i:EventTrigger EventName="MouseLeftButtonDown">
  4. <local:ColorAnimationBehavior FillColor="Red"/>
  5. </i:EventTrigger>
  6. </i:Interaction.Triggers>
  7. </Rectangle>

单击矩形时,它应从黑色变为红色.

猜你在找的C#相关文章