Skip to content

[BUG] InvalidateMeasure doesn't call MeasureOverride after the first call. #3239

Open
@DanTravison

Description

@DanTravison

Description

I have two different cases where this occurs. The scenario is essentially the same for both.

SkLabel: A custom control derived from SKCanvasView
GlyphView: A custom control derived from SKCanvasView

I'm using SkiaSharp.Views.Maui.Controls Version 3.116.1. I haven't tried it on earlier versions.

In both cases, I'm attempting to resize the SKCanvasView based on the contents.

For SkLabel, I define various properties to configure the font to use to draw the text. The propertyChanged handles each call InvalidateMeasure.

The desired size is calculated in MeasureSize based on the text and the font properties.

After the first successful MeasureOverride, I trigger a change to one of the font properties, such as FontSize. InvalidateMeasure is called but MeasureOverride is not called and the canvas is not resized.

I've debugged into the InvalidateMeasure call to see the handler resolve to SKCanvasViewHandlerSkiaSharp.Views.Maui.Handlers.SKCanvasViewHandler


Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.Element.Handler.get() Line 380 C#
Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.VisualElement.Handler.get() Line 1054 C#
Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.VisualElement.InvalidateMeasureOverride() Line 2142 C#
Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.VisualElement.Microsoft.Maui.IView.InvalidateMeasure() Line 2137 C#
Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.VisualElement.InvalidateMeasureInternal(Microsoft.Maui.Controls.InvalidationEventArgs eventArgs) Line 1712 C#
Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.VisualElement.InvalidateMeasureInternal(Microsoft.Maui.Controls.Internals.InvalidationTrigger trigger) Line 1699 C#
Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.VisualElement.InvalidateMeasure() Line 1616 C#
GlyphViewer.dll!GlyphViewer.Controls.SkLabel.InvalidateTextMetrics() Line 300 C#


Once it resolves I reach the _commandMapper?.Invoke but I'm not able to debug into it.

_commandMapper?.Invoke(this, VirtualView, command, args);


Microsoft.Maui.dll!Microsoft.Maui.Handlers.ElementHandler.Invoke(string command, object args) Line 94 C#
Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.VisualElement.InvalidateMeasureOverride() Line 2143 C#
Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.VisualElement.Microsoft.Maui.IView.InvalidateMeasure() Line 2137 C#
Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.VisualElement.InvalidateMeasureInternal(Microsoft.Maui.Controls.InvalidationEventArgs eventArgs) Line 1712 C#
Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.VisualElement.InvalidateMeasureInternal(Microsoft.Maui.Controls.Internals.InvalidationTrigger trigger) Line 1699 C#
Microsoft.Maui.Controls.dll!Microsoft.Maui.Controls.VisualElement.InvalidateMeasure() Line 1616 C#
GlyphViewer.dll!GlyphViewer.Controls.SkLabel.InvalidateTextMetrics() Line 300 C#


The scenario for GlyphView is simpler since it has a single value that changes the size but the failure is the same. After the first MeasureOverride call, InvalidateMeasure no longer results subsequent MeasureOverride calls.

Code

The SkLabel issue is illustrated here: https://github.com/DanTravison/GlyphViewer/blob/Preferences/Controls/SkLabel.cs

  • Refer to the comments in InvalidateTextMetrics and MeasureOverride.
  • In each case, explicitly setting HeightRequest in these two methods is required to workaround the issue.

The GlyphView issue is here:
https://github.com/DanTravison/GlyphViewer/blob/Preferences/Views/GlyphView.cs

  • Refer to the comments in OnGlyphChanged().
  • Again, explicitly setting HeightRequest is required to workaround the issue.

To repro The SkLabel case:
1: Sync the repro and use the Preferences branch
2: Edit Controls\SkLabel and comment out the two calls to setting HeightRequest.
3: Build/Run the app
4: Select the gear icon in the upper left.
5: Use any of the sliders adjacent to the font option sizes and not that the same text does not change.

I'll see if I can repro this with a simpler app.

Expected Behavior

After calling InvalidateMeasure, MeasureOverride should be called prior to calling OnPaintSurface

Actual Behavior

After the first MeasureOverride occurs, calling InvalidateMeasure no longer causes MeasureOverride to occur.

Version of SkiaSharp

3.116.0 (Current)

Last Known Good Version of SkiaSharp

2.88.9 (Previous)

IDE / Editor

Visual Studio (Windows)

Platform / Operating System

Windows

Platform / Operating System Version

I've only tested this on Windows 11 so far.

Devices

Windows 11 Desktop

Relevant Screenshots

No response

Relevant Log Output

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions