dotnet/wpf · error · InvalidOperationException

SR.Manipulation_ManipulationNotEnabled

Error message

SR.Manipulation_ManipulationNotEnabled

What it means

Manipulation.AddManipulator throws InvalidOperationException with SR.Manipulation_ManipulationNotEnabled when element.IsManipulationEnabled is false. A custom IManipulator can only be attached to an element that has manipulation enabled via ManipulationMode. WPF requires the element be opted into manipulation processing before manipulators may be added.

Solutions

  1. Set element.IsManipulationEnabled = true (or ManipulationMode to a value other than None) before calling AddManipulator
  2. Verify no code path resets ManipulationMode to None prior to the call
  3. Guard the call with an IsManipulationEnabled check

Example fix

// before
Manipulation.AddManipulator(element, myManipulator); // throws: not enabled
// after
if (!element.IsManipulationEnabled)
{
    element.IsManipulationEnabled = true;
}
Manipulation.AddManipulator(element, myManipulator);
Defensive patterns

Strategy: validation

Validate before calling

if (element == null || manipulator == null) throw new ArgumentNullException(nameof(element));
if (!element.IsManipulationEnabled) element.IsManipulationEnabled = true;

Type guard

static bool CanAddManipulator(UIElement e) => e != null && e.IsManipulationEnabled;

Try / catch

try { Manipulation.AddManipulator(element, manipulator); }
catch (InvalidOperationException) { element.IsManipulationEnabled = true; Manipulation.AddManipulator(element, manipulator); }

Prevention

When it happens

Trigger: Calling Manipulation.AddManipulator(element, manipulator) on an element whose ManipulationMode is None (or unset), so IsManipulationEnabled is false.

Common situations: Registering a custom manipulator on an element that was never configured for touch manipulation, or on one whose ManipulationMode was reset to None at runtime.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Manipulation.cs:219

                return device.ManipulationPivot;
            }

            return null;
        }

        /// <summary>
        ///     Associates a manipulator with a UIElement. This will either will start an 
        ///     active manipulation or add to an existing one.
        /// </summary>
        /// <param name="element">The element with which to associate the manipulator.</param>
        /// <param name="manipulator">The manipulator, such as a TouchDevice.</param>
        public static void AddManipulator(UIElement element, IManipulator manipulator)
        {
            ArgumentNullException.ThrowIfNull(element);
            ArgumentNullException.ThrowIfNull(manipulator);
            if (!element.IsManipulationEnabled)
            {
                throw new InvalidOperationException(SR.Manipulation_ManipulationNotEnabled);
            }

            ManipulationDevice device = ManipulationDevice.AddManipulationDevice(element);
            device.AddManipulator(manipulator);
        }

        /// <summary>
        ///     Disassociates a manipulator with a UIElement. This will remove it from
        ///     an active manipulation, possibly completing it.
        /// </summary>
        /// <param name="element">The element that the manipulator used to be associated with.</param>
        /// <param name="manipulator">The manipulator, such as a TouchDevice.</param>
        public static void RemoveManipulator(UIElement element, IManipulator manipulator)
        {
            ArgumentNullException.ThrowIfNull(element);
            ArgumentNullException.ThrowIfNull(manipulator);

            if (!TryRemoveManipulator(element, manipulator))

View on GitHub (pinned to 81131a70a4)