gpt4 book ai didi

c# - 使用 MVVM 的动态 View 动画

转载 作者:太空狗 更新时间:2023-10-29 21:19:34 26 4
gpt4 key购买 nike

我一直在尝试弄清楚如何在 ViewModel 中的属性更新时有效地触发 View 中的动画,其中动画取决于所述属性的值。

我在一个只有一个 View 和 View 模型的简单应用程序中重现了我的问题。此处的目标是使用 ColorAnimation 过渡矩形的颜色变化。作为引用,我一直在使用 MVVM Foundation由 Josh Smith 打包。

示例项目可以是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 绑定(bind)两者的事实.我想我也可以在 DataContextChanged 事件中执行此操作,但是有更好的方法吗?

最佳答案

如果只是为了一些动画,我会推荐使用 Visual States。然后您可以在 View 上使用 GoToAction 行为来触发不同的动画。如果您要处理大量相似的动画,创建自己的行为将是更好的解决方案。

更新我创建了一个非常简单的行为来为矩形添加一点颜色动画。这是代码。

   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, 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# - 使用 MVVM 的动态 View 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5926079/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com