AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
26.16k stars 2.27k forks source link

ArrangeCore handling of Stretch and Margins is inconsistent with WPF #16487

Open stevemonaco opened 4 months ago

stevemonaco commented 4 months ago

Describe the bug

When an item with a Stretch alignment is arranged in an area smaller than its size, Avalonia offsets the arrange bounds by half of a computed Margin (centering?). This moves the Control outside of the finalRect bounds up and to the left.

https://github.com/AvaloniaUI/Avalonia/blob/413ff78ebb6b9204e122fb10d007f1c12bfe75b9/src/Avalonia.Base/Layout/Layoutable.cs#L671-L691

The WPF behavior is to instead treat this scenario as if the alignment were Left (and/or Top) instead of Stretch. In WPF's definitions of those, anyways.

https://github.com/dotnet/wpf/blob/df3f4bf5568830adc3ed2d3da244ee7a17d551df/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElement.cs#L4827-L4854

border-resize

To Reproduce

<Window ...>
    <Border
        Height="100"
        MinWidth="300"
        Margin="0,0,150,0"
        ClipToBounds="False">
        <Border.Background>
            <LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
                <GradientStop Offset="0" Color="Orange" />
                <GradientStop Offset="1" Color="Purple" />
            </LinearGradientBrush>
        </Border.Background>
    </Border>
</Window>

(Gradient only to demonstrate the visual more clearly. ClipToBounds shows same behavior whether true or false.)

Expected behavior

I expect either WPF behavior or for this to be documented.

However, I think Avalonia's handling, especially Left alignment (not shown, but the visual gets clipped while staying in-place), is better than WPF's preference to prefer showing the margin more than the visual.

Avalonia version

11.1.0, 11.0.10

OS

Windows

Additional context

This leads to subtle bugs in components that are direct WPF ports, namely WrapPanel. See https://github.com/AvaloniaUI/Avalonia/issues/16191#issuecomment-2207870142

I have locally been able to fix the problem with either approach: 1. customizing ArrangeCore to be more WPF-like (full margin offsetting instead of halving) or 2. direct fixes to WrapPanel. I need some feedback on this area before I can address the correct area.

SlimeNull commented 3 months ago

This also affects the porting of RelativePanel. #16769