我已经创建了一个附加的依赖性财产的故事板,目的是使我能够通话的方法在我的视图模型,当一个故事情节完成的事件:

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);
    }
}

然后我试着用它在摘要与结合的语法:

<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>

这种失败有以下例外:

系统。窗户。标记。XamlParseException发生 消息="不能转换的价值在属性"风格"为对象的类型系统。窗户。风格.不冻结这故事情节时间线上树使用跨线。错误的对象'labelHello'在标记文件'TestWpfApp;组件/window1.xaml'

是否有任何方式获得该结合法工作的一个附加ICommand财产的故事情节?

有帮助吗?

解决方案 3

要解决这个问题,我创建了一堆附加属性,称为故事板助手(的源代码此处)。我放弃了试图将它们连接到故事板本身,现在连接到任何(任意)框架元素调用一个ICommand我的视图模型完成故事板的时候,以及在我的ViewModel推出故事板绑定到特定事件。第三个附加属性指定我们正在处理的故事板:

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

其他提示

这是通过设计。如果你有一个可冻结的对象,被投入一个风格式将被冻结,以允许交叉线访问。但你的约束力基本上是一个表达其意味着它不能被冻结的数据结合为单一的螺纹。

如果你需要做到这一点,把所触发的外在框架的元素,而不是在一种风格。你可以这样做在你的网格。触发的部分。这并吸一点点因为你的风格不再是完成,你有复制的触发的,但它是一个"通过设计"的要素在WPF.

完整的答案MSDN社会论坛是 在这里,.

您可以创建一个新的可冻结派生类推出一个故事板作为一个垫片。绑定该垫片对象上的属性,以故事板的名称。这样,你就不必重复触发或将它们存储的风格之外。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top