unoplatform / uno

Build Mobile, Desktop and WebAssembly apps with C# and XAML. Today. Open source and professionally supported.
https://platform.uno
Apache License 2.0
8.61k stars 694 forks source link

`LayoutSlot` is invalid #6999

Open dr1rrb opened 2 years ago

dr1rrb commented 2 years ago

Current behavior

The LayoutInformation.GetLayoutSlot does not give same result as UWP

Expected behavior

🙃

How to reproduce it (as minimally and precisely as possible)

In a blank app

<Border x:Name="Outer" Loaded="DumpData" BorderThickness="20" HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Height="100" BorderBrush="Red" Background="Blue">
    <Border x:Name="Inner" Loaded="DumpData" HorizontalAlignment="Left" VerticalAlignment="Top" Width="10" Height="10" Background="DeepPink" />
</Border>
private void DumpData(object sender, object o)
{
    var elt = (FrameworkElement)sender;
    Console.WriteLine($"{elt.Name} layout slot:{F(LayoutInformation.GetLayoutSlot(elt))} origin: {elt.TransformToVisual(this).TransformPoint(new Point())}");

    string F(Rect rect) => $"{rect.Width:F2}x{rect.Height:F2}@{rect.X:F2},{rect.Y:F2}";
}

UWP (expected)

Inner layout slot:60.00x60.00@20.00,20.00 origin: 20,20 Outer layout slot:1920.00x1048.00@0.00,0.00 origin: 0,0

Android

Inner layout slot:10.00x10.00@0.00,0.00 origin: [20, 20] Outer layout slot:100.00x100.00@0.00,0.00 origin: [0, 0]

Workaround

None

Works on UWP/WinUI

No response

Environment

No response

NuGet package version(s)

3.10.0-dev.632

Affected platforms

Android

IDE

No response

IDE version

No response

Relevant plugins

none

Anything else we need to know?

Not validated yet on iOS

Ok on Skia and WASM

ramezgerges commented 7 months ago

I just tested this on skia. Also broken. The problem is that Loaded is fired before Arrange, so LayoutSlot will still be the default value. A simple workaround is to queue the callback.

        private void DumpData(object sender, object o)
        {
            DispatcherQueue.TryEnqueue(new Microsoft.UI.Dispatching.DispatcherQueueHandler(new Action(() =>
            {
                var elt = (FrameworkElement)sender;
                global::System.Diagnostics.Debug.WriteLine($"{elt.Name} layout slot:{F(Microsoft.UI.Xaml.Controls.Primitives.LayoutInformation.GetLayoutSlot(elt))} origin: {elt.TransformToVisual(this).TransformPoint(new Point())}");

                string F(Rect rect) => $"{rect.Width:F2}x{rect.Height:F2}@{rect.X:F2},{rect.Y:F2}";
            })));
        }

This will probably be fixed by @Youssef1313 lifecycle work.

Youssef1313 commented 3 weeks ago

This may have been fixed on Skia.