我创建了一个附加依赖属性,用于处理 Storyboards,目的是在 Storyboard 完成事件触发时调用 ViewModel 上的方法:
public static class StoryboardExtensions
{
public static ICommand GetCompletedCommand(DependencyObject target)
{
return (ICommand)target.GetValue(CompletedCommandProperty);
}
public static void SetCompletedCommand(DependencyObject target, ICommand value)
{
target.SetValue(CompletedCommandProperty, value);
}
public static readonly DependencyProperty CompletedCommandProperty =
DependencyProperty.RegisterAttached(
"CompletedCommand",
typeof(ICommand),
typeof(StoryboardExtensions),
new FrameworkPropertyMetadata(null, OnCompletedCommandChanged));
static void OnCompletedCommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
Storyboard storyboard = target as Storyboard;
if (storyboard == null) throw new InvalidOperationException("This behavior can be attached to Storyboard item only.");
storyboard.Completed += new EventHandler(OnStoryboardCompleted);
}
static void OnStoryboardCompleted(object sender, EventArgs e)
{
Storyboard item = ... // snip
ICommand command = GetCompletedCommand(item);
command.Execute(null);
}
}
然后我尝试在XAML中使用它,使用绑定语法:
<Grid>
<Grid.Resources>
<Storyboard x:Key="myStoryboard" my:StoryboardExtensions.CompletedCommand="{Binding AnimationCompleted}">
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:5" />
</Storyboard>
<Style x:Key="myStyle" TargetType="{x:Type Label}">
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=QuestionState}" Value="Correct">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource myStoryboard}" />
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Label x:Name="labelHello" Grid.Row="0" Style="{StaticResource myStyle}">Hello</Label>
</Grid>
以下是出现的异常:
System.Windows.Markup.XamlParseException 发生了 Message="无法将属性 'Style' 中的值转换为类型 'System.Windows.Style' 的对象。无法冻结此Storyboard时间线树以跨线程使用。 在标记文件 'TestWpfApp;component/window1.xaml' 中的对象 'labelHello'
是否有办法通过附加的ICommand属性使Binding语法与Storyboard正常工作?