dotnet/wpf · error · InvalidOperationException
SR.Format(SR.Invalid_IInputElement, _stylusOver.GetType())
Error message
SR.Format(SR.Invalid_IInputElement, _stylusOver.GetType())
What it means
WispStylusDevice.UpdateOverProperty (WispStylusDevice.cs:436) throws InvalidOperationException(SR.Invalid_IInputElement) when attaching IsEnabledChanged/IsVisibleChanged/IsHitTestVisibleChanged handlers to the new _stylusOver element, which is not a UIElement, ContentElement, or UIElement3D. Mirrors error 700/706 for the WispStylusDevice over-property path.
Solutions
- Make hit-testable elements derive from UIElement, ContentElement, or UIElement3D.
- Trace _stylusOver.GetType() to find which component created the element.
- Validate InputElement.IsValid on elements before they enter the stylus input path.
Example fix
// before
public class Hotspot : FrameworkElement, IInputElement { /* ok */ }
public class Hotspot2 : DependencyObject, IInputElement { /* throws */ }
// after
public class Hotspot2 : UIElement { } Defensive patterns
Strategy: type-guard
Validate before calling
static bool TracksStylusOver(object e) => e is UIElement || e is ContentElement || e is UIElement3D;
Type guard
static bool IsValidInputElement(IInputElement e) => e is UIElement || e is ContentElement || e is UIElement3D;
Try / catch
try { /* change stylus over */ } catch (InvalidOperationException ex) when (ex.Message.Contains("IInputElement")) { /* log offending type and reset stylus over state */ } Prevention
- Test stylus-over behavior with custom controls before shipping
- Derive custom input controls from supported base classes
- Audit hit-test callbacks for non-standard element types
When it happens
Trigger: ChangeStylusOver sets a new over element that is not one of the three supported input element classes; the else branch of the pattern match throws while wiring the property-change handlers.
Common situations: Custom IInputElement-based controls under the pointer; broken hit-test results returning unsupported elements; version/framework interop where a custom element type slips into stylus state.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- SR.Format(SR.Invalid_IInputElement, oldOver.GetType())
- SR.Format(SR.Invalid_IInputElement…
- SR.Format(SR.Invalid_IInputElement, relativeTo.GetType())
- SR.Format(SR.Invalid_IInputElement, _stylusOver.GetType())
- ArgumentNullException: hitTestParameters
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/57d5fe551743093b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispStylusDevice.cs:436
}
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, _stylusOver.GetType()));
}
}
// Oddly enough, update the IsStylusOver property first. This is
// so any callbacks will see the more-common IsStylusOver property
// set correctly.
UIElement.StylusOverProperty.OnOriginValueChanged(oldOver as DependencyObject, _stylusOver as DependencyObject, ref _stylusOverTreeState);
// Invalidate the IsStylusDirectlyOver property.
if (oldOver != null)
{
o = oldOver as DependencyObject;
o.SetValue(UIElement.IsStylusDirectlyOverPropertyKey, false); // Same property for ContentElements
}
if (_stylusOver != null)
{
o = _stylusOver as DependencyObject;
o.SetValue(UIElement.IsStylusDirectlyOverPropertyKey, true); // Same property for ContentElementsView on GitHub (pinned to 81131a70a4)