Storyboard没有动画自定义FrameworkElement属性

本文关键字:FrameworkElement 属性 自定义 动画 Storyboard | 更新日期: 2023-09-27 17:50:43

我有一个来自FrameworkElement的类,我希望WPF通过使用DoubleAnimation来更新它的Location属性。我将属性注册为DependendencyProperty:

public class TimeCursor : FrameworkElement
{
    public static readonly DependencyProperty LocationProperty;
    public double Location
    {
        get { return (double)GetValue(LocationProperty); }
        set
        {
            SetValue(LocationProperty, value);
        }
    }
    static TimeCursor()
    {
        LocationProperty = DependencyProperty.Register("Location", typeof(double), typeof(TimeCursor));
    }
}

下面的代码设置了故事板。

TimeCursor timeCursor;
private void SetCursorAnimation()
{
    timeCursor = new TimeCursor();
    NameScope.SetNameScope(this, new NameScope());
    RegisterName("TimeCursor", timeCursor);
    storyboard.Children.Clear();
    DoubleAnimation animation = new DoubleAnimation(LeftOffset, LeftOffset + (VerticalLineCount - 1) * HorizontalGap + VerticalLineThickness, 
                new Duration(TimeSpan.FromMilliseconds(musicDuration)), FillBehavior.HoldEnd);
    Storyboard.SetTargetName(animation, "TimeCursor");
    Storyboard.SetTargetProperty(animation, new PropertyPath(TimeCursor.LocationProperty));
    storyboard.Children.Add(animation);
}

然后我从包含上述SetCursorAnimation()方法的对象的另一个方法调用storyboard.Begin(this),该对象派生自Canvas。然而,Location属性永远不会更新(永远不会调用Location的set accessor),也不会抛出异常。我做错了什么?

Storyboard没有动画自定义FrameworkElement属性

当一个依赖属性被动画化(或者在XAML中设置,或者由Style Setter等设置)时,WPF不会调用CLR包装器,而是直接访问底层的DependencyObject和DependencyProperty对象。参见实现"包装器"一节,在定义依赖属性的清单和自定义依赖属性的含义。

为了获得关于属性更改的通知,您必须注册PropertyChangedCallback:

public class TimeCursor : FrameworkElement
{
    public static readonly DependencyProperty LocationProperty =
        DependencyProperty.Register(
            "Location", typeof(double), typeof(TimeCursor),
            new FrameworkPropertyMetadata(LocationPropertyChanged)); // register callback here
    public double Location
    {
        get { return (double)GetValue(LocationProperty); }
        set { SetValue(LocationProperty, value); }
    }
    private static void LocationPropertyChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var timeCursor = obj as TimeCursor;
        // handle Location property changes here
        ...
    }
}

还要注意,动画化依赖属性并不一定需要一个故事板。你可以简单地调用TimeCursor实例上的BeginAnimation方法:

var animation = new DoubleAnimation(LeftOffset,
    LeftOffset + (VerticalLineCount - 1) * HorizontalGap + VerticalLineThickness, 
    new Duration(TimeSpan.FromMilliseconds(musicDuration)),
    FillBehavior.HoldEnd);
timeCursor.BeginAnimation(TimeCursor.LocationProperty, animation);
相关文章:
  • 没有找到相关文章