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
- Only call Deactivate from the matching lifecycle path that previously called Activate; keep a boolean to make cleanup idempotent.
- In Dispose patterns, guard Deactivate with the same _isActive-style flag so double disposal is safe.
- 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
- Make cleanup idempotent with an _activated boolean.
- Only deactivate from the path that activated the device.
- Use try/finally around Activate/Deactivate pairs.
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
- SR.Touch_DeviceAlreadyActivated
- SR.Manipulation_ManipulationNotEnabled
- Animation_Invalid_DefaultValue
- ArgumentOutOfRangeException(nameof(value))
- ArgumentOutOfRangeException(nameof(value))
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)