Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

Application immediately crashes with exception "Invalid size returned for Measure." when putting a RelativePanel in a StackPanel

Open GNUGradyn opened this issue 1 year ago • 7 comments

Describe the bug I made a minimal repo for reproducing the error. Here is the exception

System.InvalidOperationException: Invalid size returned for Measure.
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 373
   at Avalonia.Controls.StackPanel.MeasureOverride(Size availableSize) in /_/src/Avalonia.Controls/StackPanel.cs:line 207
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 559
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.LayoutHelper.MeasureChild(ILayoutable control, Size availableSize, Thickness padding) in /_/src/Avalonia.Layout/LayoutHelper.cs:line 46
   at Avalonia.Layout.LayoutHelper.MeasureChild(ILayoutable control, Size availableSize, Thickness padding, Thickness borderThickness) in /_/src/Avalonia.Layout/LayoutHelper.cs:line 39
   at Avalonia.Controls.Presenters.ContentPresenter.MeasureOverride(Size availableSize) in /_/src/Avalonia.Controls/Presenters/ContentPresenter.cs:line 366
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 559
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.LayoutHelper.MeasureChild(ILayoutable control, Size availableSize, Thickness padding) in /_/src/Avalonia.Layout/LayoutHelper.cs:line 46
   at Avalonia.Controls.Decorator.MeasureOverride(Size availableSize) in /_/src/Avalonia.Controls/Decorator.cs:line 54
   at Avalonia.Controls.Primitives.VisualLayerManager.MeasureOverride(Size availableSize) in /_/src/Avalonia.Controls/Primitives/VisualLayerManager.cs:line 133
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 559
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.Layoutable.MeasureOverride(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 625
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 559
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.Layoutable.MeasureOverride(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 625
   at Avalonia.Controls.Window.MeasureOverride(Size availableSize) in /_/src/Avalonia.Controls/Window.cs:line 928
   at Avalonia.Controls.WindowBase.MeasureCore(Size availableSize) in /_/src/Avalonia.Controls/WindowBase.cs:line 243
   at Avalonia.Layout.Layoutable.Measure(Size availableSize) in /_/src/Avalonia.Layout/Layoutable.cs:line 364
   at Avalonia.Layout.LayoutManager.Measure(ILayoutable control) in /_/src/Avalonia.Layout/LayoutManager.cs:line 287
   at Avalonia.Layout.LayoutManager.ExecuteInitialLayoutPass() in /_/src/Avalonia.Layout/LayoutManager.cs:line 174
   at Avalonia.Controls.Window.ShowCore(Window parent) in /_/src/Avalonia.Controls/Window.cs:line 693
   at Avalonia.Controls.Window.Show() in /_/src/Avalonia.Controls/Window.cs:line 631
   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.ShowMainWindow() in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 129
   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 118
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime[T](T builder, String[] args, ShutdownMode shutdownMode) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 209
   at AvaloniaDemo.Program.Main(String[] args) in D:\code\AvaloniaDemo\AvaloniaDemo\Program.cs:line 12

To Reproduce Steps to reproduce the behavior:

Put a Relative panel in a stack panel

Expected behavior You get a relative panel in a stack panel

Screenshots image

Desktop (please complete the following information):

  • OS Windows 10
  • Version 0.10.14 (NuGet 0.10.17)

GNUGradyn avatar Jul 29 '22 02:07 GNUGradyn

If you have a simple stable repro, please provide one. It will help solving the problem.

maxkatz6 avatar Jul 29 '22 02:07 maxkatz6

It's linked at the top of the post but here it is again https://github.com/GNUGradyn/AvaloniaDemo

GNUGradyn avatar Jul 29 '22 04:07 GNUGradyn

It's been a couple weeks, any update on this?

GNUGradyn avatar Aug 11 '22 02:08 GNUGradyn

The team is working hard on getting 11.0 released. Unfortunately, not every issue can be closed immediately.

Specially your issue is tagged with help wanted. So feel free to investigate the issue further and try to send a PR if you were successful. You can ask on telegram if something is unclear.

Last but not least: if you need priority support, consider paid support. You must not do, but without it's like in any other open source project. Things are done when they are done.

Happy coding Tim

timunie avatar Aug 11 '22 04:08 timunie

Thanks Tim. I'll just use a grid for now

GNUGradyn avatar Aug 11 '22 04:08 GNUGradyn

I had a look at the issue. It happens because the StackPanel grands infinite length to one of its sides(depending on the orientation). Normally, it allows other components to calculate their size and fit into the StackPanel as expected. The RelativePanel breaks here because it requires knowing where the panel ends. So, it can place components accordingly.

In such a situation, the Grid, WrapPanel, and DockPanel layout child components based on their size. They are completely ignoring the available infinite size.

I suppose we need to apply the same logic to the RelativePanel. I can take care of it. Are there any integration tests that I need to take into account?

byme8 avatar Aug 11 '22 07:08 byme8

I was looking at this too, but I'll quit now. Here's what I found:

The code is ported from here and it honestly seems to have a really bad flaw: it defines positions on measure when it should do it on arrange. This logic was changed on https://github.com/HandyOrg/HandyControl/commit/da0c8c7bba44328456136396d2ef585b43a04f17 to fix https://github.com/HandyOrg/HandyControl/issues/430, because measure wasn't adding all horizontal/vertical sizes according to relative positions as it should. Unfortunately this wasn't fixed in the right way, which would be developing the logic for measure and keep arrange as it is, and instead the arrange logic was moved to measure, which is wrong.

Also, there is a "hack" associated with this: https://github.com/HandyOrg/HandyControl/blob/9371513a0d7dfd11263571e9cdb6611c0e285f16/src/Shared/HandyControl_Shared/Controls/Panel/RelativePanel.cs#L223-L224, which was introduced on https://github.com/HandyOrg/HandyControl/commit/916d3d12b2f04ea5115cc0088589741a64b62a0e to fix https://github.com/HandyOrg/HandyControl/issues/794.

jp2masa avatar Aug 11 '22 08:08 jp2masa