1

我有派生自 的类,FrameworkElement我希望 WPF 使用DoubleAnimation. 我将财产注册为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);
}

然后我storyboard.Begin(this)从包含上述SetCursorAnimation()方法的对象的另一个方法调用,并且该对象派生自Canvas. 但是,该Location属性永远不会更新(永远不会调用 Location 的 set 访问器)并且不会引发异常。我究竟做错了什么?

4

1 回答 1

1

当依赖属性被动画化(或在 XAML 中设置,或由样式设置器设置等)时,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);
于 2013-01-05T17:12:28.607 回答