dotnet/wpf · error · ArgumentException

SR.Format(SR.Animation_DependencyPropertyIsNotAnimatable…

Error message

SR.Format(SR.Animation_DependencyPropertyIsNotAnimatable, dp.Name, this.GetType())

What it means

UIElement.ApplyAnimationClock throws ArgumentException(SR.Animation_DependencyPropertyIsNotAnimatable, paramName "dp") when AnimationStorage.IsPropertyAnimatable reports the given DependencyProperty cannot be animated on this element. The library rejects the call early because animating non-animatable properties (not registered as animatable, or not supported on this type) is meaningless.

Solutions

  1. Animate a property registered via DependencyProperty.Register with an AnimationTimeline-compatible type, or a known animatable property (e.g. Opacity, Width).
  2. Verify the DP belongs to the element's class or an ancestor.
  3. Wrap the target in a proxy/animatable surrogate property (e.g. animate a DoubleAnimation on a Transform/Brush) if the property itself can't be animated.

Example fix

// before
rect.ApplyAnimationClock(MyControl.IsSelectedProperty, clock); // not animatable
// after
rect.ApplyAnimationClock(OpacityProperty, new DoubleAnimation(0, 1, TimeSpan.FromSeconds(1)));
Defensive patterns

Strategy: try-catch

Validate before calling

if (dp == null) throw new ArgumentNullException(nameof(dp));
// Ensure dp is an animatable property of this element's type before calling:
// e.g. prefer known animatable DPs (Opacity, Width, RenderTransform...)

Type guard

bool CanAnimate(UIElement el, DependencyProperty dp) =>
    dp.OwnerType.IsInstanceOfType(el) && (dp.PropertyType == typeof(double) || dp.PropertyType == typeof(Color) || dp.PropertyType == typeof(Point) || dp.PropertyType == typeof(Thickness));

Try / catch

try { el.ApplyAnimationClock(dp, clock); }
catch (ArgumentException ex) when (ex.ParamName == "dp") { Log.Warn($"{dp.Name} is not animatable on {el.GetType()}"); }

Prevention

When it happens

Trigger: Calling element.ApplyAnimationClock(dp, clock) where dp is a plain DependencyProperty (e.g. a custom attached property) not registered with Animatable/animation support, or a property that doesn't exist on the element's type.

Common situations: Animating a custom control's custom property that wasn't registered as animatable; passing a DP from a different type; typos leading to a non-animatable attached property.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/bf5f40df6e1893ba. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Generated/UIElement.cs:71

        /// <param name="clock">
        /// The AnimationClock that will animate the property. If parameter is null
        /// then animations will be removed from the property if handoffBehavior is
        /// SnapshotAndReplace; otherwise the method call will have no result.
        /// </param>
        /// <param name="handoffBehavior">
        /// Determines how the new AnimationClock will transition from or
        /// affect any current animations on the property.
        /// </param>
        public void ApplyAnimationClock(
            DependencyProperty dp,
            AnimationClock clock,
            HandoffBehavior handoffBehavior)
        {
            ArgumentNullException.ThrowIfNull(dp);

            if (!AnimationStorage.IsPropertyAnimatable(this, dp))
            {
                throw new ArgumentException(SR.Format(SR.Animation_DependencyPropertyIsNotAnimatable, dp.Name, this.GetType()), nameof(dp));
            }

            if (clock != null
                && !AnimationStorage.IsAnimationValid(dp, clock.Timeline))
            {
                throw new ArgumentException(SR.Format(SR.Animation_AnimationTimelineTypeMismatch, clock.Timeline.GetType(), dp.Name, dp.PropertyType), nameof(clock));
            }

            if (!HandoffBehaviorEnum.IsDefined(handoffBehavior))
            {
                throw new ArgumentException(SR.Animation_UnrecognizedHandoffBehavior);
            }

            if (IsSealed)
            {
                throw new InvalidOperationException(SR.Format(SR.IAnimatable_CantAnimateSealedDO, dp, this.GetType()));
            }

View on GitHub (pinned to 81131a70a4)