绑定到故事板上附加的行为 [英] Bind to an attached behavior on a Storyboard

查看:146
本文介绍了绑定到故事板上附加的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为Storyboard创建了一个附加的依赖属性,其目的是使我能够在Storyboard Completed事件触发时调用ViewModel上的一个方法:

I have created an attached dependency property for Storyboards, with the intention of enabling me to call a method on my ViewModel when a Storyboard Completed event fires:

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中使用它,绑定语法:

then I try to use it in XAML, with a Binding syntax:

<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'错误

System.Windows.Markup.XamlParseException occurred Message="Cannot convert the value in attribute 'Style' to object of type 'System.Windows.Style'. Cannot freeze this Storyboard timeline tree for use across threads. Error at object 'labelHello' in markup file 'TestWpfApp;component/window1.xaml'

有没有办法为了使绑定语法使用故事板附加的ICommand属性?

Is there any way to get the Binding syntax working with an attached ICommand property for a Storyboard?

推荐答案

为了解决这个问题,我创建了一个的附属属性,称为故事板助手(源代码在这里)。放弃试图将它们附加到故事板本身,现在附加到任何(任意)框架元素,以在我的ViewMo上调用ICommand del当故事板完成时,以及绑定到我的ViewModel上的特定事件以启动故事板。第三个附带的属性指定我们正在处理的故事板:

To get around this problem, I created a bunch of Attached Properties, called Storyboard Helpers (source code here). I gave up trying to attach them to the Storyboard itself, and now attach to any (arbitrary) framework element to call an ICommand on my ViewModel when the storyboard is completed, as well as binding to a particular event on my ViewModel to launch the Storyboard. A third attached property specifies the Storyboard we are dealing with:

<FrameworkElement
   my:StoryboardHelpers.Storyboard="{StaticResource rightAnswerAnimation}"
   my:StoryboardHelpers.Completed="{Binding CompletedCommand}"
   my:StoryboardHelpers.BeginEvent="{Binding StartCorrectAnswer}" />

这篇关于绑定到故事板上附加的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆