dotnet/wpf · error · ArgumentException

SR.Format(SR.Animation_DependencyPropertyIsNotAnimatable…

Error message

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

What it means

Thrown by ContentElement.ApplyAnimationClock when the supplied DependencyProperty is not animatable on this element, as determined by AnimationStorage.IsPropertyAnimatable. The library refuses to attach a clock to a property that has no animation support (e.g. a read-only or non-animatable DP), so it fails fast with an ArgumentException naming the property and element type.

Solutions

  1. Verify the target DP is actually animatable: it must be a read-write DependencyProperty registered as animatable (check dp.ReadOnly is false).
  2. Choose a different, animatable property or animate its container/ancestor instead.
  3. If animating your own DP, register it as a normal (non-read-only) DependencyProperty; read-only DPs cannot be animated directly.
  4. Check AnimationStorage.IsPropertyAnimatable(this, dp) before calling ApplyAnimationClock to fail gracefully.

Example fix

// before
contentEl.ApplyAnimationClock(UIElement.OpacityProperty, clock);
// after (Opacity is not a ContentElement DP; pick an animatable property on the element)
if (AnimationStorage.IsPropertyAnimatable(contentEl, TextElement.FontSizeProperty))
    contentEl.ApplyAnimationClock(TextElement.FontSizeProperty, clock);
Defensive patterns

Strategy: validation

Validate before calling

if (dp == null || dp.ReadOnly || !AnimationStorage.IsPropertyAnimatable(element, dp))
    throw new ArgumentException($"Property {dp?.Name} is not animatable on {element?.GetType().Name}");

Type guard

bool IsAnimatableOn(ContentElement e, DependencyProperty dp) => dp != null && !dp.ReadOnly && AnimationStorage.IsPropertyAnimatable(e, dp);

Try / catch

try { el.ApplyAnimationClock(dp, clock); }
catch (ArgumentException ex) { log.Warn($"Cannot animate {dp.Name}: {ex.Message}"); }

Prevention

When it happens

Trigger: Calling ApplyAnimationClock(dp, clock) where AnimationStorage.IsPropertyAnimatable(this, dp) returns false — e.g. dp is a read-only DependencyProperty, a non-animated custom DP, or a property registered without animation support.

Common situations: Animating a read-only property like Position or IsMouseOver; applying an animation to a custom DP the developer forgot to mark animatable; animating properties on ContentElement subclasses that only support a subset of DPs; copying animation code from UIElement to a ContentElement property that differs.

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/354e494c4a62925d. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Generated/ContentElement.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)