I’m using Avalonia 11.1 and I’d like to know the size of my TextBlock
‘s content before actually rendering it, so that I can align components properly in one go.
I can’t find any ready-to-use function or documentation dedicated to that. I tried creating a TextBlock
and calling its Measure
method, but that returned 0 for the width.
Is there a (relatively) simple way to do that ?
TL;DR
public static Size CalculateTextSize(string myText, string myFontResourceKey, int myFontSize)
{
if (Application.Current?.TryFindResource(myFontResourceKey, out object? fontObj) != true)
throw new ArgumentException($"Cannot find a resource named {myFontResourceKey} in this application's resources.");
if (!(fontObj is FontFamily myFont))
throw new ArgumentException($"The resource {myFontResourceKey} is not a FontFamily.");
var ts = TextShaper.Current;
var typeface = new Typeface(myFont);
ShapedBuffer shaped = ts.ShapeText(myText, new TextShaperOptions(typeface.GlyphTypeface, myFontSize));
var run = new ShapedTextRun(shaped, new GenericTextRunProperties(typeface, myFontSize));
return run.Size;
}
###########
The API reference at https://reference.avaloniaui.net/api/ seems to still target version 11.0 at the time i’m writing this. The Avalonia.Media.TextFormatting
namespace contains a bunch of classes related to the measuring text, but they are slightly different than version 11.1.
After some trial-and-error, i finally got it working:
- Get your font resource. In my case, it was defined in a
ResourceDictionary
xaml file at the application level, and the only function which worked to retrieve it wasStyledElement.FindResource
. It can be accessed from anywhere usingApplication.Current.FindResource("MyFontResourceKey", out object? fontObj);
- Cast it to
FontFamily
- Create a
TypeFace
from yourFontFamily
- Get a
TextShaper
instance - Get a
ShapedBuffer
(namedGlyphRun
in avalonia 11.0, it seems) from theTextShaper
- Transform it into a
ShapedTextRun
- Get the size of your rendered text from the
ShapedTextRun.Size
property.
Don’t hesitate to answer if i missed something simpler !