{"record":{"id":"7b9f4a73379db385","repo":"stride3d/stride","slug":"width-must-not-be-infinite-when-virtualizing-vertically","errorCode":null,"errorMessage":"Width must not be infinite when virtualizing vertically.","messagePattern":"Width must not be infinite when virtualizing vertically\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation.Wpf/Controls/VirtualizingTilePanel.cs","lineNumber":159,"sourceCode":"            ItemCount = -1;\n\n            var generator = ItemContainerGenerator;\n            if (generator == null)\n                return base.MeasureOverride(availableSize);\n\n            var parentItemsControl = ItemsControl.GetItemsOwner(this);\n            if (parentItemsControl == null)\n                return base.MeasureOverride(availableSize);\n\n            ItemCount = parentItemsControl.Items.Count;\n            ItemsPerLine = ItemCount;\n            lineCount = ItemsPerLine;\n\n            Size desiredSize;\n            if (Orientation == Orientation.Vertical)\n            {\n                if (double.IsPositiveInfinity(availableSize.Width))\n                    throw new InvalidOperationException(\"Width must not be infinite when virtualizing vertically.\");\n\n                ItemsPerLine = (int)Math.Ceiling(availableSize.Width - MinimumItemSpacing) / (int)(ItemSlotSize.Width + MinimumItemSpacing);\n                ItemsPerLine = Math.Max(1, Math.Min(ItemsPerLine, ItemCount));\n                lineCount = ComputeLineCount(ItemCount);\n                desiredSize = new Size(availableSize.Width, lineCount * ItemSlotSize.Height);\n            }\n            else\n            {\n                if (double.IsPositiveInfinity(availableSize.Height))\n                    throw new InvalidOperationException(\"Height must not be infinite when virtualizing horizontally.\");\n\n                ItemsPerLine = (int)Math.Ceiling(availableSize.Height - MinimumItemSpacing) / (int)Math.Ceiling(ItemSlotSize.Height + MinimumItemSpacing);\n                ItemsPerLine = Math.Max(1, Math.Min(ItemsPerLine, ItemCount));\n                lineCount = ComputeLineCount(ItemCount);\n                desiredSize = new Size(lineCount * ItemSlotSize.Width, availableSize.Height);\n            }\n\n            UpdateScrollInfo(availableSize);","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Wpf/Controls/VirtualizingTilePanel.cs#L141-L177","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n<ScrollViewer HorizontalScrollBarVisibility=\"Auto\">\n  <controls:VirtualizingTilePanel Orientation=\"Vertical\"/>\n</ScrollViewer>\n// after\n<ScrollViewer>\n  <controls:VirtualizingTilePanel Orientation=\"Vertical\"\n      HorizontalAlignment=\"Stretch\" Width=\"{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=ScrollViewer}}\"/>","handlingStrategy":"validation","validationCode":"// Ensure a finite width constraint before the panel is measured:\ntilePanel.Width = double.IsInfinity(desiredWidth) ? 800 : desiredWidth;\n// or set HorizontalAlignment=Stretch inside a Grid rather than a horizontal StackPanel.","typeGuard":"bool HasFiniteWidthConstraint(FrameworkElement el) =>\n    !double.IsPositiveInfinity(el.Width) || el.HorizontalAlignment == HorizontalAlignment.Stretch;","tryCatchPattern":"try { panelHost.UpdateLayout(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Width must not be infinite\")) { tilePanel.Width = 800; tilePanel.UpdateLayout(); }","preventionTips":["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."],"tags":["wpf","layout","virtualization","measure"],"backgroundTag":"invalid-config-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}