dotnet/maui · error · ArgumentNullException

ContentLoader

Error message

ContentLoader

What it means

FormsContentControl.OnContentLoaderChanged throws ArgumentNullException("ContentLoader") when the WPF DependencyProperty is set to null. LightContentControl_SizeChanged immediately dereferences ContentLoader, so null would NRE on the next resize unless rejected here.

Source

Thrown at src/Compatibility/Core/src/WPF/Controls/FormsContentControl.cs:44

			set { SetValue(ContentLoaderProperty, value); }
		}

		public FormsContentControl()
		{
			this.DefaultStyleKey = typeof(FormsContentControl);
			this.SizeChanged += LightContentControl_SizeChanged;
		}

		private void LightContentControl_SizeChanged(object sender, SizeChangedEventArgs e)
		{
			this.ContentLoader.OnSizeContentChanged(this, Source);
		}

		private static void OnContentLoaderChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
		{
			if (e.NewValue == null)
			{
				throw new ArgumentNullException("ContentLoader");
			}
		}

		private static void OnSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
		{
			((FormsContentControl)o).OnSourceChanged(e.OldValue, e.NewValue);
		}

		private void OnSourceChanged(object oldValue, object newValue)
		{
			if (newValue != null && newValue.Equals(oldValue))
				return;

			var localTokenSource = new CancellationTokenSource();
			this.tokenSource = localTokenSource;

			var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
			var task = this.ContentLoader.LoadContentAsync(this, oldValue, newValue, this.tokenSource.Token);

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Assign a concrete IContentLoader (FormsContentLoader or DefaultContentLoader) before the control measures its content.
  2. Use FallbackValue on the binding so a null source resolves to a default loader.
  3. Never null ContentLoader during teardown; dispose the underlying page instead.
  4. Verify any {StaticResource}/{DynamicResource} reference resolves at runtime.

Example fix

// before
control.ContentLoader = null;

// after
control.ContentLoader = new FormsContentLoader();
Defensive patterns

Strategy: validation

Validate before calling

control.ContentLoader = control.ContentLoader ?? new FormsContentLoader();

Type guard

static bool HasValidLoader(FormsContentControl c) => c.ContentLoader != null;

Try / catch

try { control.ContentLoader = loader; }
catch (ArgumentNullException) { control.ContentLoader = new FormsContentLoader(); }

Prevention

When it happens

Trigger: Setting FormsContentControl.ContentLoader to null in XAML or code; a binding to ContentLoader that resolves to null; clearing the property without assigning a replacement loader.

Common situations: Resource lookup failure for the ContentLoader; DataContext unset so the binding evaluates to null; explicit teardown nulling the loader; loader swap that assigns null before constructing the new loader.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/89fe487131ad2c8e. Report an issue: GitHub.