未针对故事板上附加的 属性 执行回调

Callback not executing for attached property on storyboard

使用以下定义,当符合 INotifyPropertyChanged 的​​视图模型中的 Signal 更改其值时,OnSignalChanged 永远不会执行,当然,动画不会播放。我误解了一些基本的东西吗? TestCommand 只是将 Signal 从 false 设置为 true。

Public Class StoryboardSignalManager
    Public Shared SignalProperty As DependencyProperty = DependencyProperty.RegisterAttached("Signal",
                                                                                         GetType(Boolean),
                                                                                         GetType(StoryboardSignalManager),
                                                                                         New PropertyMetadata(AddressOf OnSignalChanged))
    Public Shared Function GetSignal(d As DependencyObject) As Boolean?
        Return DirectCast(d.GetValue(SignalProperty), Boolean?)
    End Function
    Public Shared Sub SetSignal(d As DependencyObject, value As Object)
        d.SetValue(SignalProperty, value)
    End Sub

    Private Shared Sub OnSignalChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
        Dim value As Boolean = DirectCast(e.NewValue, Boolean)
        Dim storyboard As Storyboard = DirectCast(d, Storyboard)

        If value Then
            storyboard.Begin()
        Else
            storyboard.Stop()
        End If
    End Sub
End Class
<Grid>
    <Grid.Resources>
        <Storyboard x:Key="Fade" local:StoryboardSignalManager.Signal="{Binding Signal}">
            <DoubleAnimationUsingKeyFrames Storyboard.Target="{Binding ElementName=TextBlock}" Storyboard.TargetProperty="Opacity">
                <EasingDoubleKeyFrame KeyTime="00:00:00.00" Value="1" />
                <EasingDoubleKeyFrame KeyTime="00:00:01.00" Value="0" />
                <EasingDoubleKeyFrame KeyTime="00:00:02.00" Value="1" />
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Grid.Resources>
    <StackPanel>
        <TextBlock x:Name="TextBlock" Text="test" />
        <Button Width="100" Height="50" Command="{Binding TestCommand}" />
    </StackPanel>
</Grid>

我测试了你的代码(虽然是在 C# 中),根据经验,你的 PropertyChangedCallback 似乎没有被调用,因为情节提要是一种资源,而且它似乎没有在正确的时间加载附加的属性 附上这么说...

要了解我在说什么,您可以为 usercontrol/view 代码后面的

添加一个 Loaded 事件处理程序
    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        var board = (this.FindResource("Fade") as Storyboard);
    }

如果我没记错的话,这将回答你关于回调未被执行的问题;在加载控件时,您将使用 FindResource 强制加载资源,这将使附加的 属性 正常工作。

但是,使这项工作似乎会导致回调函数中 storyboard.Begin() 周围出现 Whosebug 异常。我不知道为什么会这样(也许是一些隐藏的 WPF 魔法......如果你知道为什么请告诉我!)

鉴于此,我建议您将动画制作成这样的东西:

<Grid local:StoryBoardSignalManager.Signal="{Binding Signal, Mode=TwoWay}" >
    <Grid.Resources>
        <Style x:Key="FadeAnimationStyle" TargetType="TextBlock">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=(local:StoryBoardSignalManager.Signal), RelativeSource={RelativeSource AncestorType=Grid}}" Value="True">
                    <DataTrigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
                                    <EasingDoubleKeyFrame KeyTime="00:00:00.00" Value="1" />
                                    <EasingDoubleKeyFrame KeyTime="00:00:01.00" Value="0" />
                                    <EasingDoubleKeyFrame KeyTime="00:00:02.00" Value="1" />
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Resources>
    <StackPanel>
        <TextBlock x:Name="TextBlock" Text="test" Style="{StaticResource FadeAnimationStyle}"/>
        <Button Width="100" Height="50" Command="{Binding TestCommand}" />
    </StackPanel>
</Grid>