dotnet/wpf · error · InvalidOperationException
SR.Format(SR.Invalid_IInputElement, oldOver.GetType())
Error message
SR.Format(SR.Invalid_IInputElement, oldOver.GetType())
What it means
WispLogic stylus-over (hover) tracking unsubscribes IsEnabled/IsVisible/IsHitTestVisible change handlers from the previous element under the stylus. If oldOver is not UIElement, ContentElement, or UIElement3D, it throws InvalidOperationException naming its type, because over-tracking handler management only supports those element kinds.
Solutions
- Ensure hit-test/over targets resolve to UIElement/ContentElement/UIElement3D (wrap DrawingVisuals in a UIElement host)
- Verify InputElement.IsValid on elements entering stylus-over tracking
- Audit custom hit-test overrides that return non-element visuals directly
Example fix
// before SetStylusOver(drawingVisual, ...); // unsupported over target // after SetStylusOver(FindAncestor<UIElement>(drawingVisual), ...);
Defensive patterns
Strategy: type-guard
Validate before calling
if (element is UIElement || element is ContentElement || element is UIElement3D) { /* safe for stylus-over tracking */ } Type guard
bool IsSupportedOverElement(IInputElement e) => e is UIElement || e is ContentElement || e is UIElement3D;
Try / catch
try { UpdateStylusOver(newElement); }
catch (InvalidOperationException ex) { Log.Warn("Stylus-over target unsupported", ex); } Prevention
- Ensure hit-test results resolve to supported input elements
- Host raw visuals in UIElement wrappers
- Avoid custom hit-test overrides that return non-element visuals
When it happens
Trigger: The element previously tracked as StylusDirectlyOver was not a supported input element type — typically after hover state was seeded with a non-element DependencyObject; thrown when stylus-over state changes (PROMOTE/mouse-promotion or actual pen movement).
Common situations: Custom IInputElement hit-test results fed into stylus-over tracking; hover over DrawingVisual-hosted content without a wrapping element; mixed mouse-promotion code paths using non-element visuals.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- SR.Format(SR.Invalid_IInputElement, oldCapture.GetType())
- SR.Format(SR.Invalid_IInputElement…
- SR.Stylus_PenContextFailure
- SR.Format(SR.Invalid_IInputElement…
- SR.Format(SR.Invalid_IInputElement, oldCapture.GetType())
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/e3225ae79ed2de4e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispLogic.cs:2175
}
else if (o is ContentElement ce)
{
ce.IsEnabledChanged -= _overIsEnabledChangedEventHandler;
// NOTE: there are no IsVisible or IsHitTestVisible properties for ContentElements.
//
// ce.IsVisibleChanged -= _overIsVisibleChangedEventHandler;
// ce.IsHitTestVisibleChanged -= _overIsHitTestVisibleChangedEventHandler;
}
else if (o is UIElement3D uie3D)
{
uie3D.IsEnabledChanged -= _overIsEnabledChangedEventHandler;
uie3D.IsVisibleChanged -= _overIsVisibleChangedEventHandler;
uie3D.IsHitTestVisibleChanged -= _overIsHitTestVisibleChangedEventHandler;
}
else
{
throw new InvalidOperationException(SR.Format(SR.Invalid_IInputElement, oldOver.GetType()));
}
}
if (_stylusOver != null)
{
o = _stylusOver as DependencyObject;
if (o is UIElement uie)
{
uie.IsEnabledChanged += _overIsEnabledChangedEventHandler;
uie.IsVisibleChanged += _overIsVisibleChangedEventHandler;
uie.IsHitTestVisibleChanged += _overIsHitTestVisibleChangedEventHandler;
}
else if (o is ContentElement ce)
{
ce.IsEnabledChanged += _overIsEnabledChangedEventHandler;
// NOTE: there are no IsVisible or IsHitTestVisible properties for ContentElements.
//
// ce.IsVisibleChanged += _overIsVisibleChangedEventHandler;View on GitHub (pinned to 81131a70a4)