stride3d/stride · error · InvalidOperationException
Width must not be infinite when virtualizing vertically.
Error message
Width must not be infinite when virtualizing vertically.
What it means
VirtualizingTilePanel arranges items in fixed-size slots and, when oriented vertically, needs a finite available width to compute how many items fit per line for virtualization. MeasureOverride throws InvalidOperationException if availableSize.Width is PositiveInfinity, since an unbounded width makes per-line item count (and therefore which items to virtualize) indeterminate.
Solutions
- Constrain width: set explicit Width, or HorizontalAlignment="Stretch" inside a Grid instead of a horizontal StackPanel.
- Replace enclosing StackPanel with a Grid or DockPanel that gives finite constraint.
- If horizontal scrolling is needed, scroll vertically and give the panel a finite viewport width.
Example fix
// before
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<controls:VirtualizingTilePanel Orientation="Vertical"/>
</ScrollViewer>
// after
<ScrollViewer>
<controls:VirtualizingTilePanel Orientation="Vertical"
HorizontalAlignment="Stretch" Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=ScrollViewer}}"/> Defensive patterns
Strategy: validation
Validate before calling
// Ensure a finite width constraint before the panel is measured: tilePanel.Width = double.IsInfinity(desiredWidth) ? 800 : desiredWidth; // or set HorizontalAlignment=Stretch inside a Grid rather than a horizontal StackPanel.
Type guard
bool HasFiniteWidthConstraint(FrameworkElement el) =>
!double.IsPositiveInfinity(el.Width) || el.HorizontalAlignment == HorizontalAlignment.Stretch; Try / catch
try { panelHost.UpdateLayout(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Width must not be infinite")) { tilePanel.Width = 800; tilePanel.UpdateLayout(); } Prevention
- Never place vertically-oriented virtualizing tile panels inside horizontal StackPanels or auto-width containers.
- Give the panel a bounded width via Grid layout or explicit Width.
- Avoid HorizontalScrollBarVisibility=Auto on ancestor ScrollViewers hosting these panels.
When it happens
Trigger: Placing the vertically-oriented VirtualizingTilePanel in a container that measures with infinite width, e.g. inside a StackPanel with horizontal orientation, a ScrollViewer with HorizontalScrollBarVisibility=Auto, or a Grid row/column with Auto width.
Common situations: Dropping the panel into a StackPanel (default infinite measure in the stacking direction); hosting inside a horizontally scrolling surface; forgetting to constrain the control's Width/HorizontalAlignment.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Height must not be infinite when virtualizing horizontally.
- Unable to reach the ItemsPresenter of the associated…
- BringItemToView cannot be used when the tree view is…
- entity must contain a non-null asset entity.
- A dispatcher lock must be created from a different thread…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/7b9f4a73379db385.
Report an issue: GitHub.
Appendix: source
Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Controls/VirtualizingTilePanel.cs:159
ItemCount = -1;
var generator = ItemContainerGenerator;
if (generator == null)
return base.MeasureOverride(availableSize);
var parentItemsControl = ItemsControl.GetItemsOwner(this);
if (parentItemsControl == null)
return base.MeasureOverride(availableSize);
ItemCount = parentItemsControl.Items.Count;
ItemsPerLine = ItemCount;
lineCount = ItemsPerLine;
Size desiredSize;
if (Orientation == Orientation.Vertical)
{
if (double.IsPositiveInfinity(availableSize.Width))
throw new InvalidOperationException("Width must not be infinite when virtualizing vertically.");
ItemsPerLine = (int)Math.Ceiling(availableSize.Width - MinimumItemSpacing) / (int)(ItemSlotSize.Width + MinimumItemSpacing);
ItemsPerLine = Math.Max(1, Math.Min(ItemsPerLine, ItemCount));
lineCount = ComputeLineCount(ItemCount);
desiredSize = new Size(availableSize.Width, lineCount * ItemSlotSize.Height);
}
else
{
if (double.IsPositiveInfinity(availableSize.Height))
throw new InvalidOperationException("Height must not be infinite when virtualizing horizontally.");
ItemsPerLine = (int)Math.Ceiling(availableSize.Height - MinimumItemSpacing) / (int)Math.Ceiling(ItemSlotSize.Height + MinimumItemSpacing);
ItemsPerLine = Math.Max(1, Math.Min(ItemsPerLine, ItemCount));
lineCount = ComputeLineCount(ItemCount);
desiredSize = new Size(lineCount * ItemSlotSize.Width, availableSize.Height);
}
UpdateScrollInfo(availableSize);View on GitHub (pinned to 96fad776d2)