dotnet/wpf · error · ArgumentNullException

ArgumentOutOfRangeException(nameof(oldProperty))

Error message

ArgumentOutOfRangeException(nameof(oldProperty))

What it means

ExtendedPropertiesChangedEventArgs (internal) throws ArgumentNullException named 'oldProperty' when both oldProperty and newProperty are null. Note the message is a null-argument exception even though the true condition is 'both null'.

Solutions

  1. Ensure at least one of oldProperty/newProperty is non-null before constructing
  2. Add a guard that skips notification when both are null

Example fix

// before
new ExtendedPropertiesChangedEventArgs(oldProperty, newProperty);
// after
if (oldProperty != null || newProperty != null) new ExtendedPropertiesChangedEventArgs(oldProperty, newProperty);
Defensive patterns

Strategy: validation

Validate before calling

if (oldProperty == null && newProperty == null) return; // skip notification

Type guard

static bool HasEither(ExtendedProperty o, ExtendedProperty n) => o != null || n != null;

Try / catch

try { new ExtendedPropertiesChangedEventArgs(oldProperty, newProperty); } catch (ArgumentNullException) { /* both null: skip */ }

Prevention

When it happens

Trigger: Internal code paths constructing ExtendedPropertiesChangedEventArgs(null, null); only reachable via reflection, private copy of WPF source, or subclassed/derived event plumbing.

Common situations: Custom ink framework code mimicking WPF internals; debugging WPF source where an ExtendedProperty changed notification was built from two missing values.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/Events.cs:158

    /// delegate used for event handlers that are called when the Custom attributes associated with an object have changed.
    /// </summary>
    internal delegate void ExtendedPropertiesChangedEventHandler(object sender, ExtendedPropertiesChangedEventArgs e);

    /// <summary>
    /// Event Arg used when the Custom attributes associated with an object have changed.
    /// </summary>
    internal class ExtendedPropertiesChangedEventArgs : EventArgs
    {
        private ExtendedProperty _oldProperty;
        private ExtendedProperty _newProperty;

        /// <summary>Constructor</summary>
        internal ExtendedPropertiesChangedEventArgs(ExtendedProperty oldProperty,
                                                    ExtendedProperty newProperty)
        {
            if ( oldProperty == null && newProperty == null )
            {
                throw new ArgumentNullException(nameof(oldProperty));
            }
            _oldProperty = oldProperty;
            _newProperty = newProperty;
        }

        /// <summary>
        /// The value of the previous property.  If the Changed event was caused
        /// by an ExtendedProperty being added, this value is null
        /// </summary>
        internal ExtendedProperty OldProperty
        {
            get { return _oldProperty; }
        }

        /// <summary>
        /// The value of the new property.  If the Changed event was caused by 
        /// an ExtendedProperty being removed, this value is null
        /// </summary>

View on GitHub (pinned to 81131a70a4)