我正在寻找一种干净的方式来启动具有动态值的动画。基本上我想做一个动画,其中一个元素根据另一个元素的数据改变宽度。假设我有一个文本属性为绑定的TextBlock。当这个属性改变时,我想要一个可视元素说一个Rectangle,以便我们做一个DoubleAnimation,将宽度从之前的值改为新值。
如果可能的话,我正试图远离将代码放入我的视图中。我已经研究过DataTriggers,但它们似乎要求你知道它的价值,例如Enum。在我的情况下,只是需要触发故事板的值更改,动画需要从当前(上一个)值开始,并很好地移动到新值。
任何想法。也许我只是错过了一处房产。
答案 0 :(得分:15)
这是我最终解决的问题。要根据我的ViewModel中的数据执行动画,我使用了DataTrigger。以下是我的控制风格。
<Style TargetType="Grid" x:Key="DetailRotation" >
<Style.Triggers>
<DataTrigger Binding="{Binding Path=AnimationState}" Value="New">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="EndAnimation" />
<BeginStoryboard Name="NewAnimation">
<Storyboard>
<ThicknessAnimation Storyboard.TargetProperty="Margin" From="0,30,0,0" To="0,0,0,0" Duration="0:0:1" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
</DataTrigger.ExitActions>
</DataTrigger>
<DataTrigger Binding="{Binding Path=AnimationState}" Value="End">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="NewAnimation" />
<BeginStoryboard Name="EndAnimation">
<Storyboard>
<ThicknessAnimation Storyboard.TargetProperty="Margin" From="0,0,0,0" To="0,-20,0,0" Duration="0:0:1"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
答案 1 :(得分:1)
您可以使用Attached Properties探索将所需逻辑连接到您想要的故事板/动画。
这不一定会阻止您编写代码,但它会将其与视图分开,并允许它在多个视图中重复使用。
答案 2 :(得分:0)
由于动画修改的属性无法在动画“上下文”之外设置,我想出了一个代码解决方案,因为我无法在XAML中有效地执行相同的操作。
private void UserControl_IsVisibleChanged(object sender,
DependencyPropertyChangedEventArgs e)
{
if (this.Visibility == Visibility.Visible)
{
DoubleAnimation fadeIn = new DoubleAnimation();
fadeIn.From = 1d;
fadeIn.To = 1d;
fadeIn.Duration = new Duration(new TimeSpan(0, 0, 0));
DoubleAnimation fade = new DoubleAnimation();
fade.From = 1d;
fade.To = 0d;
fade.BeginTime = TimeSpan.FromSeconds(5);
fade.Duration = new Duration(new TimeSpan(0, 0, 1));
NameScope.SetNameScope(this, new NameScope());
this.RegisterName(this.Name, this);
Storyboard.SetTargetName(fadeIn, this.Name);
Storyboard.SetTargetProperty(fadeIn, new PropertyPath
(UIElement.OpacityProperty));
Storyboard.SetTargetName(fade, this.Name);
Storyboard.SetTargetProperty(fade, new PropertyPath
(UIElement.OpacityProperty));
Storyboard sb = new Storyboard();
sb.Children.Add(fadeIn);
sb.Children.Add(fade);
sb.Completed += new EventHandler(sb_Completed);
sb.Begin(this);
}
}
void sb_Completed(object sender, EventArgs e)
{
this.Visibility = Visibility.Hidden;
}
答案 3 :(得分:0)
实际上,您希望将DoubleAnimation.ToProperty
绑定到ViewModel
属性并为实际控件设置动画。问题是在ToProperty
更改时应继续动画。我的解决方案将所有这些逻辑封装到包含MarkupExtenstion
的{{1}}。
Binding
您可以对其他动画类执行相同的操作以设置其他类型的动画。