dotnet/wpf · error · InvalidOperationException

SR.Format(SR.Invalid_IInputElement, _stylusOver.GetType())

Error message

SR.Format(SR.Invalid_IInputElement, _stylusOver.GetType())

What it means

In UpdateOverProperty, when subscribing stylus-over handlers on the NEW over element (_stylusOver), an InvalidOperationException (SR.Invalid_IInputElement with _stylusOver.GetType()) is thrown if the element is not UIElement, ContentElement, or UIElement3D.

Solutions

  1. Make hover-sensitive custom elements inherit UIElement (or ContentElement/UIElement3D)
  2. Avoid implementing IInputElement on plain DependencyObjects that participate in stylus input
  3. Verify hit-test targets are supported types in input handling code

Example fix

// before
class MyHoverTarget : DependencyObject, IInputElement { ... }
// after
class MyHoverTarget : UIElement { ... }
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(hoverTarget is UIElement || hoverTarget is ContentElement || hoverTarget is UIElement3D)) return;

Type guard

static bool IsSupportedInputElement(IInputElement e) => e is UIElement || e is ContentElement || e is UIElement3D;

Try / catch

try { RegisterStylusOver(hoverTarget); }
catch (InvalidOperationException) { /* ignore or log unsupported hover target */ }

Prevention

When it happens

Trigger: Stylus pointer moving over an element that is a DependencyObject/IInputElement but not one of the three supported WPF element types, during over-property update.

Common situations: Hovering over custom controls implementing IInputElement directly; plugin visual systems integrated into the WPF tree without inheriting supported base classes.

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


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/371dacc2b9d22d95. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Pointer/PointerLogic.cs:655

                    }
                    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 element3D)
                    {
                        element3D.IsEnabledChanged += _overIsEnabledChangedEventHandler;
                        element3D.IsVisibleChanged += _overIsVisibleChangedEventHandler;
                        element3D.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;

View on GitHub (pinned to 81131a70a4)