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

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

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

示例项目可以是downloaded here.

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

MainWindow.xaml

<Window x:Class="MVVM.ColorAnimation.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ColorAnimation="clr-namespace:MVVM.ColorAnimation" Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <ColorAnimation:MainWindowviewmodel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="40" />
        </Grid.RowDefinitions>

        <Rectangle Margin="10">
            <Rectangle.Fill>
                <SolidColorBrush Color="{Binding Color}"/>
            </Rectangle.Fill>
        </Rectangle>

        <StackPanel Orientation="Horizontal" Grid.Row="1">
            <Button Command="{Binding BlueCommand}" Width="100">Blue</Button>
            <Button Command="{Binding GreenCommand}" Width="100">Green</Button>
        </StackPanel>
    </Grid>
</Window>

MainWindowviewmodel.cs

namespace MVVM.ColorAnimation
{
    using System.Windows.Input;
    using System.Windows.Media;

    using MVVM;

    public class MainWindowviewmodel : ObservableObject
    {
        private ICommand blueCommand;
        private ICommand greenCommand;

        public ICommand BlueCommand
        {
            get
            {
                return this.blueCommand ?? (this.blueCommand = new RelayCommand(this.TurnBlue));
            }
        }

        private void TurnBlue()
        {
            this.Color = Colors.Blue;
        }

        public ICommand GreenCommand
        {
            get
            {
                return this.greenCommand ?? (this.greenCommand = new RelayCommand(this.TurnGreen));
            }
        }

        private void TurnGreen()
        {
            this.Color = Colors.Green;
        }

        private Color color = Colors.Red;

        public Color Color
        {
            get
            {
                return this.color;
            }

            set
            {
                this.color = value;
                RaisePropertyChanged("Color");
            }
        }     
    }
}

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

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

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

解决方法

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

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

public class ColorAnimationBehavior : TriggerAction<FrameworkElement>
    {
        #region Fill color
        [Description("The background color of the rectangle")]
        public Color FillColor
        {
            get { return (Color)GetValue(FillColorProperty); }
            set { SetValue(FillColorProperty,value); }
        }

        public static readonly DependencyProperty FillColorProperty =
            DependencyProperty.Register("FillColor",typeof(Color),typeof(ColorAnimationBehavior),null);
        #endregion

        protected override void Invoke(object parameter)
        {
            var rect = (Rectangle)AssociatedObject;

            var sb = new Storyboard();
            sb.Children.Add(CreateVisibilityAnimation(rect,new Duration(new TimeSpan(0,1)),FillColor));

            sb.Begin();
        }

        private static ColorAnimationUsingKeyFrames CreateVisibilityAnimation(DependencyObject element,Duration duration,Color color)
        {
            var animation = new ColorAnimationUsingKeyFrames();

            animation.KeyFrames.Add(new SplineColorKeyFrame { KeyTime = new TimeSpan(duration.TimeSpan.Ticks),Value = color });

            Storyboard.SetTargetProperty(animation,new PropertyPath("(Shape.Fill).(SolidColorBrush.Color)"));
            Storyboard.SetTarget(animation,element);

            return animation;
        }

    }

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

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

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

猜你在找的C#相关文章