HandyOrg/HandyControl · error · ArgumentNullException

owner

Error message

owner

What it means

The internal GlowEdge constructor requires a GlowWindow owner to know which window it decorates, and throws ArgumentNullException(nameof(owner)) when null is passed. The edge also tracks CreatedGlowEdges/DisposedGlowEdges counters and delegates state (like IsDeferringChanges) to the owner window, so a null owner is unusable.

Solutions

  1. Let GlowWindow create its own edges internally instead of constructing GlowEdge yourself (the constructor is internal).
  2. If you must construct it, pass the live GlowWindow instance and verify it is non-null before the call.
  3. Ensure dependency injection or reflection code resolves the GlowWindow correctly and is not passing null.

Example fix

// before
var edge = new GlowEdge(null, Dock.Top);
// after
var glowWindow = new GlowWindow();
var edge = new GlowEdge(glowWindow, Dock.Top); // owner must be the live window
Defensive patterns

Strategy: validation

Validate before calling

if (owner == null) throw new InvalidOperationException("GlowEdge requires a live GlowWindow owner");
var edge = new GlowEdge(owner, dock);

Type guard

static bool HasOwner(GlowWindow owner) => owner != null;

Try / catch

try { var edge = new GlowEdge(owner, dock); } catch (ArgumentNullException) { // owner was null; create the GlowWindow first or skip the edge
}

Prevention

When it happens

Trigger: Constructing GlowEdge directly with a null GlowWindow (e.g. reflection, a custom glow implementation, or DI mistakenly supplying null).

Common situations: Custom window chrome code instantiating glow edges manually instead of letting GlowWindow create them; refactoring that breaks the owner window creation order.

Related errors


AI-assisted analysis of HandyOrg/HandyControl@2c0875ebd6 (2026-09-14). Data as JSON: /api/errors/2676ac1dcdb5866f. Report an issue: GitHub.

Appendix: source

Thrown at src/Shared/HandyControl_Shared/Data/GlowWindow/GlowEdge.cs:58

    private bool _isActive;

    private bool _isVisible;

    private int _left;

    private bool _pendingDelayRender;

    private int _top;

    private int _width;

    internal static long CreatedGlowEdges { get; private set; }

    internal static long DisposedGlowEdges { get; private set; }

    internal GlowEdge(GlowWindow owner, Dock orientation)
    {
        _targetWindow = owner ?? throw new ArgumentNullException(nameof(owner));
        _orientation = orientation;
        CreatedGlowEdges += 1L;
    }

    private bool IsDeferringChanges => _targetWindow.DeferGlowChangesCount > 0;

    private static ushort SharedWindowClassAtom
    {
        get
        {
            if (_sharedWindowClassAtom == 0)
            {
                var wndclass = default(InteropValues.WNDCLASS);

                wndclass.cbClsExtra = 0;
                wndclass.cbWndExtra = 0;
                wndclass.hbrBackground = IntPtr.Zero;
                wndclass.hCursor = IntPtr.Zero;

View on GitHub (pinned to 2c0875ebd6)