dotnet/wpf · error · ArgumentException
SR.Stylus_MustBeDownToCallReset
Error message
SR.Stylus_MustBeDownToCallReset
What it means
DynamicRenderer.Reset re-renders the current stroke using the stylus/mouse position, and requires the pointing device to be down (in contact). If the stylus device is InAir or the primary mouse's left button is released, it throws ArgumentException with SR.Stylus_MustBeDownToCallReset.
Solutions
- Check the device state before calling: only call Reset when stylusDevice.InAir is false or Mouse.PrimaryDevice.LeftButton is Pressed.
- Call Reset from events that guarantee contact, such as StylusMove/StylusDown, not StylusUp/StylusLeave.
- Track stroke state yourself (a bool set on Down, cleared on Up) and gate the Reset call.
- Guard the stylus path explicitly: if a stylusDevice is supplied, verify it is not InAir.
Example fix
// before
void OnStylusUp(object sender, StylusEventArgs e)
{
dynamicRenderer.Reset(e.StylusDevice); // throws: pen is up
}
// after
void OnStylusMove(object sender, StylusEventArgs e)
{
if (!e.StylusDevice.InAir)
dynamicRenderer.Reset(e.StylusDevice);
} Defensive patterns
Strategy: validation
Validate before calling
bool stylusDown = stylusDevice != null
? !stylusDevice.InAir
: Mouse.PrimaryDevice.LeftButton == MouseButtonState.Pressed;
if (stylusDown)
dynamicRenderer.Reset(stylusDevice); Type guard
static bool IsPointingDeviceDown(StylusDevice stylusDevice) =>
stylusDevice != null ? !stylusDevice.InAir
: Mouse.PrimaryDevice.LeftButton == MouseButtonState.Pressed; Try / catch
try
{
dynamicRenderer.Reset(stylusDevice);
}
catch (ArgumentException ex) when (ex.ParamName == nameof(stylusDevice))
{
// device not down; skip reset or defer to next StylusMove
} Prevention
- Only call Reset during StylusMove/StylusDown-style events where contact is guaranteed.
- Track stroke state with a bool set on Down and cleared on Up.
- Check InAir / LeftButton before every Reset call.
- Never call Reset from click handlers or timers without verifying device state.
When it happens
Trigger: Calling DynamicRenderer.Reset() (or the overload taking a stylusDevice) while the stylus is hovering (InAir) or while the mouse left button is released — e.g. from an event that fires without the pen touching the digitizer.
Common situations: Calling Reset on StylusUp/StylusLeave events after the pen lifted; calling Reset from a button click or timer when no active stroke is in progress; tablet-hover configurations where the pen reports InAir.
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
- ArgumentOutOfRangeException(nameof(oldProperty))
- ArgumentOutOfRangeException(nameof(percentageWithinBounds))
- ArgumentOutOfRangeException(nameof(percentageWithinLasso))
- ArgumentOutOfRangeException(percentageWithinBounds)
- ArgumentOutOfRangeException(percentageWithinLasso)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/1ef17cd64ccdc7d4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/DynamicRenderer.cs:249
{
// NOTE: stylusDevice == null means the mouse device.
// Nothing to do if root visual not queried or not hookup up to element yet.
if (_mainContainerVisual == null || _applicationDispatcher == null || !IsActiveForInput)
return;
// Ensure on UIContext.
_applicationDispatcher.VerifyAccess();
// Make sure the stylusdevice specified (or mouse if null stylusdevice) is currently in
// down state!
bool inAir = (stylusDevice != null) ?
stylusDevice.InAir :
Mouse.PrimaryDevice.LeftButton == MouseButtonState.Released;
if (inAir)
{
throw new ArgumentException(SR.Stylus_MustBeDownToCallReset, nameof(stylusDevice));
}
// Avoid reentrancy due to lock() call.
using(_applicationDispatcher.DisableProcessing())
{
lock(__siLock)
{
AbortAllStrokes(); // stop any current inking strokes
// Now create new si and insert it in the list.
StrokeInfo si = new StrokeInfo(DrawingAttributes,
(stylusDevice != null) ? stylusDevice.Id : 0,
Environment.TickCount, GetCurrentHostVisual());
_strokeInfoList.Add(si);
si.IsReset = true;
if (stylusPoints != null)
{View on GitHub (pinned to 81131a70a4)