dotnet/wpf · error · ArgumentException

SR.InvalidCtorParameterNoNaN

Error message

SR.InvalidCtorParameterNoNaN

What it means

The two-parameter VirtualizationCacheLength constructor throws ArgumentException (InvalidCtorParameterNoNaN) when cacheBeforeViewport is NaN. NaN is rejected because virtualization cache sizes must be finite pixel/item counts.

Solutions

  1. Validate the value with double.IsNaN before constructing and substitute a sane default.
  2. Fix the computation that yields NaN (guard against division by zero).
  3. Use double.IsFinite to also exclude infinities if appropriate for your scenario.

Example fix

// before
var len = new VirtualizationCacheLength(itemWidth / viewportWidth, 0);
// after
var ratio = viewportWidth > 0 ? itemWidth / viewportWidth : 1;
var len = new VirtualizationCacheLength(ratio, 0);
Defensive patterns

Strategy: validation

Validate before calling

if (!double.IsNaN(cacheBeforeViewport)) { var len = new VirtualizationCacheLength(cacheBeforeViewport, cacheAfterViewport); }

Type guard

bool IsValidCacheLength(double v) => !double.IsNaN(v);

Try / catch

try { var len = new VirtualizationCacheLength(before, after); } catch (ArgumentException) { var len = new VirtualizationCacheLength(0, 0); }

Prevention

When it happens

Trigger: Calling new VirtualizationCacheLength(double.NaN, x), commonly with a value produced by double division 0/0, an uninitialized double from a binding, or Math operations that yield NaN.

Common situations: Computing cache length dynamically (e.g. dividing viewport size by item size when the viewport is 0) and feeding the NaN result into the constructor or into VirtualizingPanel.CacheLength.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/VirtualizationCacheLength.cs:68

        /// Constructor, initializes the CacheBeforeViewport and the CacheAfterViewport to their sizes. Units are specified as a seperate VisualizationCacheLengthUnit property.
        /// </summary>
        /// <param name="cacheBeforeAndAfterViewport">Value to be stored by this VirtualizationCacheLength 
        /// instance as the cacheBeforeViewport and cacheAfterViewport.</param>
        /// <exception cref="ArgumentException">
        /// If <c>cacheBeforeAndAfterViewport</c> parameter is <c>double.NaN</c>
        /// or <c>cacheBeforeAndAfterViewport</c> parameter is <c>double.NegativeInfinity</c>
        /// or <c>cacheBeforeAndAfterViewport</c> parameter is <c>double.PositiveInfinity</c>.
        /// </exception>
        public VirtualizationCacheLength(double cacheBeforeAndAfterViewport)
            : this(cacheBeforeAndAfterViewport, cacheBeforeAndAfterViewport)
        {
        }

        public VirtualizationCacheLength(double cacheBeforeViewport, double cacheAfterViewport)
        {
            if (double.IsNaN(cacheBeforeViewport))
            {
                throw new ArgumentException(SR.Format(SR.InvalidCtorParameterNoNaN, "cacheBeforeViewport"));
            }

            if (double.IsNaN(cacheAfterViewport))
            {
                throw new ArgumentException(SR.Format(SR.InvalidCtorParameterNoNaN, "cacheAfterViewport"));
            }

            _cacheBeforeViewport = cacheBeforeViewport;
            _cacheAfterViewport = cacheAfterViewport;
        }

        #endregion Constructors

        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

View on GitHub (pinned to 81131a70a4)