dotnet/wpf · error · InvalidOperationException
SR.EndHitTestingCalled
Error message
SR.EndHitTestingCalled
What it means
After EndHitTesting() is called the IncrementalHitTester is invalid; further AddPoints calls throw InvalidOperationException (SR.EndHitTestingCalled). This enforces the hit-tester's lifecycle: create → test → EndHitTesting.
Solutions
- Create a new IncrementalHitTester (via stroke.GetIncrementalHitTester/GetIncrementalStrokeHitTester) after EndHitTesting instead of reusing the old one
- Track tester validity with a flag or check and skip AddPoints once invalidated
- Wrap in try-catch InvalidOperationException to tolerate post-dispose events
Example fix
// before if (_hitTester != null) _hitTester.AddPoints(pts); // after if (_hitTester != null && _hitTesterValid) _hitTester.AddPoints(pts);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!_hitTesterValid) return;
Type guard
bool CanTest(IncrementalHitTester t, bool valid) => t != null && valid;
Try / catch
try { tester.AddPoints(pts); } catch (InvalidOperationException) { _hitTesterValid = false; } Prevention
- Set a validity flag when calling EndHitTesting and check it before every AddPoints
- Dispose/replace stored testers at the start of each erase operation
- Avoid async continuations that may run after EndHitTesting
When it happens
Trigger: Calling AddPoints/AddPoint after EndHitTesting() on the same tester — e.g. reusing a tester stored in a field across stroke re-render or after cancellation.
Common situations: Long-lived hit-tester fields not reset when a new stroke erase begins; event handlers firing after hit-testing was concluded; async continuations running after EndHitTesting.
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
- Property data must be a non-reference variant compatible…
- SR.EmptyArrayNotAllowedAsArgument
- SR.GestureRecognizerNotAvailable
- ArgumentNullException: hitTestParameters
- ArgumentOutOfRangeException(nameof(oldProperty))
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/3740b41c75f70d99.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/IncrementalHitTester.cs:46
AddPoints(new Point[1] { point });
}
/// <summary>
/// Adds an array of points representing an incremental move of the hit-testing tool
/// </summary>
/// <param name="points">points representing an incremental move of the hitting tool</param>
public void AddPoints(IEnumerable<Point> points)
{
ArgumentNullException.ThrowIfNull(points);
if (IEnumerablePointHelper.GetCount(points) == 0)
{
throw new System.ArgumentException(SR.EmptyArrayNotAllowedAsArgument, nameof(points));
}
if (!_fValid)
{
throw new System.InvalidOperationException(SR.EndHitTestingCalled);
}
System.Diagnostics.Debug.Assert(_strokes != null);
AddPointsCore(points);
}
/// <summary>
/// Adds a StylusPacket representing an incremental move of the hit-testing tool
/// </summary>
/// <param name="stylusPoints">stylusPoints</param>
public void AddPoints(StylusPointCollection stylusPoints)
{
ArgumentNullException.ThrowIfNull(stylusPoints);
if (stylusPoints.Count == 0)
{
throw new System.ArgumentException(SR.EmptyArrayNotAllowedAsArgument, nameof(stylusPoints));View on GitHub (pinned to 81131a70a4)