我正在编写一个MVVM应用程序,并开始添加一些动画效果。我希望在ViewModel上调用某个东西来启动故事板。这篇博客提供了一个有希望的方法,但它实际上并不起作用。IDChanged处理程序出现了某些问题,不能正常触发。
我还发现可以在EventTriggers上启动动画,但不知道如何在ViewModel上引发EventTrigger。
我还发现可以在EventTriggers上启动动画,但不知道如何在ViewModel上引发EventTrigger。
我通过使用DataTrigger将其绑定到ViewModel中的属性来实现此操作。当“FlashingBackGround”属性设置为“ON”时,故事板动画会启动。
还要确保在项目中包含对“Microsoft.Expression.Interactions”的引用。
XAML:(直接放在根节点中)
<Window
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
x:Name="window" >
...
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding FlashingBackground, Mode=OneWay}" Value="ON">
<ei:ControlStoryboardAction Storyboard="{StaticResource MyAnimation}"
ControlStoryboardOption="Play"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
...
</Window>
视图模型(ViewModel):
private void TurnOnFlashingBackround()
{
FlashingBackground = "ON";
}
private string _FlashingBackround = "OFF";
public string FlashingBackground
{
get { return _FlashingBackround; }
private set
{
if (FlashingBackground == value)
{
return;
}
_FlashingBackround = value;
this.OnPropertyChanged("FlashingBackground");
}
}
public new event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
最后,Viewmodel必须继承自"INotifyPropertyChanged"
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
SetAnimationBindings();
}
private void SetAnimationBindings()
{
_dialogStartPosition = mbFolderBrowse.Margin;
var propName = "StartDialogAnimation";
var binding = new Binding(propName) { Mode = BindingMode.TwoWay };
this.SetBinding(DialogAnimationProperty, binding);
propName = "StartProgressAnimation";
binding = new Binding(propName) { Mode = BindingMode.TwoWay };
this.SetBinding(ProgressAnimationProperty, binding);
}
#region Animation Properties
#region DialogAnimation
public static readonly DependencyProperty DialogAnimationProperty =
DependencyProperty.Register("DialogAnimation", typeof(bool),
typeof(Manage), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnDialogAnimationChanged));
public bool DialogAnimation
{
get { return (bool)this.GetValue(DialogAnimationProperty); }
set
{
var oldValue = (bool)this.GetValue(DialogAnimationProperty);
if (oldValue != value) this.SetValue(DialogAnimationProperty, value);
}
}
private static void OnDialogAnimationChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
Manage m = o as Manage;
if ((bool)e.NewValue == true)
m.SlideInDialogPanel(); // animations
else
m.SlideOutDialogPanel();
}
#endregion
视图模型:
public bool StartDialogAnimation
{
get { return _startDialogAnimation; }
set
{
if (_startDialogAnimation != value)
{
_startDialogAnimation = value;
RaisePropertyChanged("StartDialogAnimation");
}
}
}
我在虚拟机中有一个属性,反映了应用程序的状态。视图中被动画处理的元素具有数据触发器,当虚拟机属性具有特定值时,启动故事板。
最终,我在我的ViewModel中添加了一个AnimationStarted事件,并使用键字符串指定了它所代表的动画。然后,在视图中,我通过编程方式创建了动画,订阅了AnimationStarted事件,并在其触发时启动相应的动画。