dotnet/wpf · error · InvalidOperationException

SR.Touch_DeviceNotActivated

Error message

SR.Touch_DeviceNotActivated

What it means

TouchDevice.Deactivate unregisters the touch device (releases capture, detaches, removes from the active device list). It requires the device to currently be active; calling it when _isActive is false throws InvalidOperationException(Touch_DeviceNotActivated). Deactivate must mirror a prior successful Activate call.

Solutions

  1. Only call Deactivate from the matching lifecycle path that previously called Activate; keep a boolean to make cleanup idempotent.
  2. In Dispose patterns, guard Deactivate with the same _isActive-style flag so double disposal is safe.
  3. Let the WPF input system deactivate the device itself when the device is removed instead of forcing Deactivate.

Example fix

// before
public void Dispose()
{
    Deactivate(); // throws if never activated or already deactivated
}

// after
private bool _activated;
public void Dispose()
{
    if (_activated)
    {
        Deactivate();
        _activated = false;
    }
}
Defensive patterns

Strategy: validation

Validate before calling

if (!device.IsActive) return; // nothing to deactivate

Try / catch

try { device.Deactivate(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("activated"))
{
    // not active — nothing to do
}

Prevention

When it happens

Trigger: Calling Deactivate() on a TouchDevice that was never activated; calling Deactivate twice (the second call throws); calling Deactivate after the device was already torn down by the system (e.g. the tablet/device went away and deactivate already happened implicitly).

Common situations: Cleanup code in a custom touch provider that unconditionally calls Deactivate in Dispose; double disposal (Dispose called from both finalizer and explicit path); asymmetric lifecycle where an error path skipped Activate but cleanup still calls Deactivate.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/TouchDevice.cs:719

            if (_activeDevices.Count == 1)
            {
                _isPrimary = true;
            }

            _isActive = true;

            if (Activated != null)
            {
                Activated(this, EventArgs.Empty);
            }
        }

        protected void Deactivate()
        {
            if (!_isActive)
            {
                throw new InvalidOperationException(SR.Touch_DeviceNotActivated);
            }

            Capture(null);

            DetachTouchDevice();
            RemoveActiveDevice(this);

            _isActive = false;
            _manipulatingElement = null;

            if (Deactivated != null)
            {
                Deactivated(this, EventArgs.Empty);
            }
        }

        /// <summary>
        ///     Forces the TouchDevice to resynchronize.

View on GitHub (pinned to 81131a70a4)