{"record":{"id":"1ef17cd64ccdc7d4","repo":"dotnet/wpf","slug":"sr-stylus-mustbedowntocallreset","errorCode":null,"errorMessage":"SR.Stylus_MustBeDownToCallReset","messagePattern":"SR\\.Stylus_MustBeDownToCallReset","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/DynamicRenderer.cs","lineNumber":249,"sourceCode":"        {\n            // NOTE: stylusDevice == null means the mouse device.\n\n            // Nothing to do if root visual not queried or not hookup up to element yet.\n            if (_mainContainerVisual == null || _applicationDispatcher == null || !IsActiveForInput)\n                return;\n            \n            // Ensure on UIContext.\n            _applicationDispatcher.VerifyAccess();\n\n            // Make sure the stylusdevice specified (or mouse if null stylusdevice) is currently in \n            // down state!\n            bool inAir = (stylusDevice != null) ? \n                            stylusDevice.InAir : \n                            Mouse.PrimaryDevice.LeftButton == MouseButtonState.Released;\n            \n            if (inAir)\n            {\n                throw new ArgumentException(SR.Stylus_MustBeDownToCallReset, nameof(stylusDevice));\n            }\n\n            // Avoid reentrancy due to lock() call.\n            using(_applicationDispatcher.DisableProcessing())\n            {\n                lock(__siLock)\n                {\n                    AbortAllStrokes(); // stop any current inking strokes\n\n                    // Now create new si and insert it in the list.\n                    StrokeInfo si = new StrokeInfo(DrawingAttributes, \n                                                   (stylusDevice != null) ? stylusDevice.Id : 0, \n                                                   Environment.TickCount, GetCurrentHostVisual());\n                    _strokeInfoList.Add(si);\n                    si.IsReset = true;\n\n                    if (stylusPoints != null)\n                    {","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/DynamicRenderer.cs#L231-L267","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvoid OnStylusUp(object sender, StylusEventArgs e)\n{\n    dynamicRenderer.Reset(e.StylusDevice); // throws: pen is up\n}\n\n// after\nvoid OnStylusMove(object sender, StylusEventArgs e)\n{\n    if (!e.StylusDevice.InAir)\n        dynamicRenderer.Reset(e.StylusDevice);\n}","handlingStrategy":"validation","validationCode":"bool stylusDown = stylusDevice != null\n    ? !stylusDevice.InAir\n    : Mouse.PrimaryDevice.LeftButton == MouseButtonState.Pressed;\nif (stylusDown)\n    dynamicRenderer.Reset(stylusDevice);","typeGuard":"static bool IsPointingDeviceDown(StylusDevice stylusDevice) =>\n    stylusDevice != null ? !stylusDevice.InAir\n        : Mouse.PrimaryDevice.LeftButton == MouseButtonState.Pressed;","tryCatchPattern":"try\n{\n    dynamicRenderer.Reset(stylusDevice);\n}\ncatch (ArgumentException ex) when (ex.ParamName == nameof(stylusDevice))\n{\n    // device not down; skip reset or defer to next StylusMove\n}","preventionTips":["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."],"tags":["wpf","stylus","ink","invalid-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}