Several platform views (SKCanvasViewControl, SKGLViewControl, PlatformGraphicsView, ProgressRingVisual) extend Avalonia.Controls.Control directly without overriding MeasureOverride. The base Control.MeasureOverride() returns default(Size), i.e. (0, 0).
This is not a problem when the MAUI virtual view uses the default HorizontalOptions="Fill" / VerticalOptions="Fill", because LayoutAlignment.Fill maps to HorizontalAlignment.Stretch, and Avalonia's ArrangeCore gives a stretched control the full parent-allocated space regardless of DesiredSize.
However, when the MAUI view sets HorizontalOptions="Start" (or Center, End), the handler maps it to HorizontalAlignment.Left (or Center, Right). In this case Avalonia's ArrangeCore clamps the final render size to DesiredSize — which is (0, 0). The control collapses to zero width/height, its Bounds become empty, and Render() returns early without drawing anything.
On the WinUI backend this does not occur because the WinUI handler for SKCanvasView does not limit the arranged size based on DesiredSize in the same way.
Affected controls
| Control |
File |
SKCanvasViewControl |
src/Avalonia.Controls.Maui.SkiaSharp.Views/Controls/SKCanvasViewControl.cs |
SKGLViewControl |
src/Avalonia.Controls.Maui.SkiaSharp.Views/Controls/SKGLViewControl.cs |
PlatformGraphicsView |
src/Avalonia.Controls.Maui/Platform/PlatformGraphicsView.cs |
ProgressRingVisual |
(similar pattern) |
Note: GifImage in the same codebase does override MeasureOverride, so it is unaffected.
Reproduction
- Create a custom control extending
SKCanvasView that overrides MeasureOverride to return a non-zero size.
- Place it in a layout with
HorizontalOptions="Start".
- Run on the Avalonia backend — the control is invisible.
- Run on the WinUI backend — the control renders correctly.
Minimal XAML:
<sk:SKButton Text="Primary button"
HorizontalOptions="Start"
ButtonColor="#512BD4"
TextColor="White"
HeightRequest="48" />
Root cause
In ViewHandler.GetDesiredSize(), the handler calls platformView.Measure(constraint) and reads platformView.DesiredSize. Since these controls return (0, 0) from MeasureOverride, the Avalonia layout system considers their desired size to be zero.
When ViewHandler.PlatformArrange() later calls platformView.Arrange(rect), Avalonia's ArrangeCore applies the alignment:
// Simplified from Avalonia's ArrangeCore
var size = HorizontalAlignment == Stretch
? finalSize
: DesiredSize; // ← (0, 0) for these controls
This shrinks the render bounds to zero, causing Render() to early-return.
Suggested fix
Override MeasureOverride in each affected control to return the available size:
protected override Size MeasureOverride(Size availableSize)
{
return availableSize;
}
This is safe because MAUI's layout system already positions and sizes children through CrossPlatformMeasure / CrossPlatformArrange / PlatformArrange with explicit bounds. The Avalonia alignment is essentially redundant for MAUI-managed views — the platform view just needs to fill whatever frame MAUI allocates.
Workaround (consumer-side)
As a workaround without modifying this library, the control author can force the platform view to Stretch alignment in OnHandlerChanged:
protected override void OnHandlerChanged()
{
base.OnHandlerChanged();
if (Handler?.PlatformView is Avalonia.Controls.Control ctrl)
{
ctrl.HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch;
ctrl.VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch;
}
}
This works because MAUI's PlatformArrange supplies the exact frame, and Stretch prevents ArrangeCore from shrinking it.
Environment
- Avalonia.Controls.Maui: current main (
90bcad8)
- Avalonia: 12.0.0-rc1
- SkiaSharp: 3.119.4-preview.1.1
- OS: Windows 10 / Debian 11
- Reproducible on: Avalonia desktop backend only (WinUI backend unaffected)
Several platform views (
SKCanvasViewControl,SKGLViewControl,PlatformGraphicsView,ProgressRingVisual) extendAvalonia.Controls.Controldirectly without overridingMeasureOverride. The baseControl.MeasureOverride()returnsdefault(Size), i.e.(0, 0).This is not a problem when the MAUI virtual view uses the default
HorizontalOptions="Fill"/VerticalOptions="Fill", becauseLayoutAlignment.Fillmaps toHorizontalAlignment.Stretch, and Avalonia'sArrangeCoregives a stretched control the full parent-allocated space regardless ofDesiredSize.However, when the MAUI view sets
HorizontalOptions="Start"(orCenter,End), the handler maps it toHorizontalAlignment.Left(orCenter,Right). In this case Avalonia'sArrangeCoreclamps the final render size toDesiredSize— which is(0, 0). The control collapses to zero width/height, itsBoundsbecome empty, andRender()returns early without drawing anything.On the WinUI backend this does not occur because the WinUI handler for
SKCanvasViewdoes not limit the arranged size based onDesiredSizein the same way.Affected controls
SKCanvasViewControlsrc/Avalonia.Controls.Maui.SkiaSharp.Views/Controls/SKCanvasViewControl.csSKGLViewControlsrc/Avalonia.Controls.Maui.SkiaSharp.Views/Controls/SKGLViewControl.csPlatformGraphicsViewsrc/Avalonia.Controls.Maui/Platform/PlatformGraphicsView.csProgressRingVisualNote:
GifImagein the same codebase does overrideMeasureOverride, so it is unaffected.Reproduction
SKCanvasViewthat overridesMeasureOverrideto return a non-zero size.HorizontalOptions="Start".Minimal XAML:
Root cause
In
ViewHandler.GetDesiredSize(), the handler callsplatformView.Measure(constraint)and readsplatformView.DesiredSize. Since these controls return(0, 0)fromMeasureOverride, the Avalonia layout system considers their desired size to be zero.When
ViewHandler.PlatformArrange()later callsplatformView.Arrange(rect), Avalonia'sArrangeCoreapplies the alignment:This shrinks the render bounds to zero, causing
Render()to early-return.Suggested fix
Override
MeasureOverridein each affected control to return the available size:This is safe because MAUI's layout system already positions and sizes children through
CrossPlatformMeasure/CrossPlatformArrange/PlatformArrangewith explicit bounds. The Avalonia alignment is essentially redundant for MAUI-managed views — the platform view just needs to fill whatever frame MAUI allocates.Workaround (consumer-side)
As a workaround without modifying this library, the control author can force the platform view to
Stretchalignment inOnHandlerChanged:This works because MAUI's
PlatformArrangesupplies the exact frame, andStretchpreventsArrangeCorefrom shrinking it.Environment
90bcad8)