dotnet/maui · error · InvalidOperationException
ViewCell must have a View
Error message
ViewCell must have a View
What it means
Thrown by the Android ViewCellRenderer when cell.View is null at render time. A ViewCell must contain a child View to be measured and displayed; rendering proceeds only after confirming the View is set.
Source
Thrown at src/Controls/src/Core/Compatibility/Handlers/ListView/Android/ViewCellRenderer.cs:49
BindableProperty unevenRows = null, rowHeight = null;
#pragma warning disable CS0618 // Type or member is obsolete
if (ParentView is TableView)
{
unevenRows = TableView.HasUnevenRowsProperty;
rowHeight = TableView.RowHeightProperty;
}
else if (ParentView is ListView)
{
cell.IsContextActionsLegacyModeEnabled = item.On<PlatformConfiguration.Android>().GetIsContextActionsLegacyModeEnabled();
unevenRows = ListView.HasUnevenRowsProperty;
rowHeight = ListView.RowHeightProperty;
}
#pragma warning restore CS0618 // Type or member is obsolete
if (cell.View == null)
throw new InvalidOperationException($"ViewCell must have a {nameof(cell.View)}");
var view = (IPlatformViewHandler)cell.View.ToHandler(cell.FindMauiContext());
cell.View.IsPlatformEnabled = true;
// If the convertView is null we don't want to return the same view, we need to return a new one.
// We should probably do this for ListView as well
#pragma warning disable CS0618 // Type or member is obsolete
if (ParentView is TableView)
{
view.ToPlatform().RemoveFromParent();
}
else
{
ViewCellContainer c = view.ToPlatform().GetParentOfType<ViewCellContainer>();
if (c != null)
return c;
}View on GitHub (pinned to f377ff1c5e)
Solutions
- Always set ViewCell.View to a non-null View before the cell is measured (synchronously in the template factory).
- Provide a placeholder/loading View as the default and swap content later if needed.
- Validate in the DataTemplate factory that the returned cell has a View.
Example fix
// before
listView.ItemTemplate = new DataTemplate(() => new ViewCell());
// after
listView.ItemTemplate = new DataTemplate(() =>
{
return new ViewCell { View = new Label { Text = "Loading" } };
}); Defensive patterns
Strategy: validation
Validate before calling
static ViewCell MakeCell() =>
new ViewCell { View = new Label { Text = "Loading" } }; Type guard
static bool HasView(ViewCell c) => c.View is not null;
Prevention
- Always set ViewCell.View synchronously in the template factory.
- Use a placeholder View for async-loaded content.
- Validate the cell before it enters measurement.
When it happens
Trigger: Defining a ViewCell in XAML/code without a View child. Setting View to null dynamically. A DataTemplate whose factory returns a ViewCell before View is assigned (e.g. async population not yet complete at measure time).
Common situations: Empty <ViewCell/> in XAML. ViewCell where the View is loaded asynchronously/lazily and not set before the list measures. Conditional View assignment that skips the assignment branch.
Related errors
- ViewCell must have a View
- ItemTemplate count has exceeded the limit of {ViewTypeCount}
- ViewCell must have a {nameof(cell.View)}
- View for cell must implement {nameof(INativeElementView)} to
- ItemTemplate count has exceeded the limit of {ViewTypeCount}
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/ffa2d4920ec3fbc9.
Report an issue: GitHub.