dotnet/wpf · error · InvalidOperationException

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

Error message

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

What it means

PointerLogic.UpdateStylusCapture unsubscribes capture-change event handlers from the previous stylus-capture element. If oldCapture is a DependencyObject that is neither UIElement, ContentElement, nor UIElement3D, an InvalidOperationException (SR.Invalid_IInputElement with the concrete type) is thrown, since the element is not a supported IInputElement.

Solutions

  1. Only capture UIElement, ContentElement, or UIElement3D instances
  2. Cast/verify the element type before calling Stylus.Capture
  3. Implement the custom capture element as a subclass of one of the supported types

Example fix

// before
Stylus.Capture(myCustomInputElement, CaptureMode.Element);
// after
if (myCustomInputElement is UIElement || myCustomInputElement is ContentElement || myCustomInputElement is UIElement3D)
{
    Stylus.Capture(myCustomInputElement, CaptureMode.Element);
}
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

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

Try / catch

try { Stylus.Capture(element, CaptureMode.Element); }
catch (InvalidOperationException ex) when (ex.Message.Contains("IInputElement")) { /* reject unsupported element */ }

Prevention

When it happens

Trigger: An object that is an IInputElement/DependencyObject but not one of the three supported element types being assigned as stylus capture (via Stylus.Capture) and then released/updated.

Common situations: Custom classes implementing IInputElement passed to Stylus.Capture; third-party frameworks with their own input element types used with WPF pointer/stylus capture.

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/d369d88a05829395. Report an issue: GitHub.

Appendix: source

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

                    {
                        element.IsEnabledChanged -= _captureIsEnabledChangedEventHandler;
                        element.IsVisibleChanged -= _captureIsVisibleChangedEventHandler;
                        element.IsHitTestVisibleChanged -= _captureIsHitTestVisibleChangedEventHandler;
                    }
                    else if (o is ContentElement ce)
                    {
                        // NOTE: there are no IsVisible or IsHitTestVisible properties for ContentElements.
                        ce.IsEnabledChanged -= _captureIsEnabledChangedEventHandler;
                    }
                    else if (o is UIElement3D element3D)
                    {
                        element3D.IsEnabledChanged -= _captureIsEnabledChangedEventHandler;
                        element3D.IsVisibleChanged -= _captureIsVisibleChangedEventHandler;
                        element3D.IsHitTestVisibleChanged -= _captureIsHitTestVisibleChangedEventHandler;
                    }
                    else
                    {
                        throw new InvalidOperationException(SR.Format(SR.Invalid_IInputElement, oldCapture.GetType())); 
                    }
                }

                if (_stylusCapture != null)
                {
                    o = _stylusCapture as DependencyObject;
                    if (o is UIElement element)
                    {
                        element.IsEnabledChanged += _captureIsEnabledChangedEventHandler;
                        element.IsVisibleChanged += _captureIsVisibleChangedEventHandler;
                        element.IsHitTestVisibleChanged += _captureIsHitTestVisibleChangedEventHandler;
                    }
                    else if (o is ContentElement ce)
                    {
                        // NOTE: there are no IsVisible or IsHitTestVisible properties for ContentElements.
                        ce.IsEnabledChanged += _captureIsEnabledChangedEventHandler;
                    }
                    else if (o is UIElement3D element3D)

View on GitHub (pinned to 81131a70a4)