A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
Hi @Muthukumar Madasamy ,
Thanks for reaching out.
When I use only an Image inside this layout, the measure call consistently returns (0,0) only on Windows. On other platforms like Android and iOS, the image eventually measures correctly after a few calls.
The official document has state that: "Each platform handles layout slightly differently. However, .NET MAUI's cross-platform layout process aims to be as platform-agnostic as possible."
For more information, you can check this link: https://learn.microsoft.com/en-us/dotnet/maui/user-interface/layouts/custom?view=net-maui-9.0#layout-process
Below are answers to your questions:
“Is this a known issue with image measurement in MAUI on Windows?”
When the custom layout calls Measure() on an Image, WinUI has often not finished loading or decoding the image source yet, so the native control has no size information available during the initial measure pass. As a result, MAUI reports (0,0).
Android and iOS decode images earlier in the lifecycle, so this issue rarely appears on those platforms.
https://github.com/dotnet/maui/issues/7531
https://github.com/dotnet/maui/issues/4880
https://github.com/dotnet/maui/issues/26094
“Is there a recommended workaround to ensure the image is measured correctly on the first pass?”
Yes. The practical workaround is to trigger a second measure pass after the image has either loaded or had its source assigned. This ensures the custom layout measures the image at a point when it actually has a valid size.
A common approach is to invalidate the layout during the Loaded event:
image.Loaded += (_, _) => layout.InvalidateMeasure();
Note: The official documentation for VisualElement.Loaded notes that it may occur before the element has been measured, so it cannot guarantee final sizing on its own. However, in real-world cases - especially on Windows with asynchronous image loading - this event is still useful because it fires after the native control is created, allowing the subsequent measure pass to capture the correct size once decoding completes.
Some developers also listen for source changes to trigger an updated layout:
image.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(Image.Source))
layout.InvalidateMeasure();
};
This uses public APIs only and avoids relying on undocumented internal events. For reference, see the MAUI Image control documentation which explains image loading behavior and IsLoading.
“Could this be related to how Windows handles image loading or layout invalidation?”
Yes. This behavior is directly caused by how the Windows platform handles asynchronous image loading and layout invalidation inside WinUI. Specifically:
- Images are loaded and decoded asynchronously on Windows.
- The first layout pass usually occurs before the image has finished decoding.
- The WinUI
Imagecontrol does not automatically trigger a second layout pass for custom layouts. - As a result, the initial
Measure()returns(0,0)until you explicitly invalidate measure from your code.
You can also reference the MAUI Image element interface documentation which explains how source changes propagate internally.
This is why custom layouts that depend on accurate child measurements need an explicit re-measure trigger on Windows.
If your issue persists, you can create a new issue on the official MAUI GitHub repository: https://github.com/dotnet/maui/issues
Hope this helps! If my answer was helpful - kindly follow the instructions here so others with the same problem can benefit as well.