Forum Xamarin.Forms

How to calculate or measure width of a string ?

Vimal.4745Vimal.4745 USMember ✭✭

Hi All,
My requirement is to calculate the width of a text that is inside a Label. This calculated width is set as the width of the Label. In other words the labels width is equal to the width of the text inside it. Is there any method to achieve this in XForms like we have methods in Xamarin.Android and Xamarin.iOS ? Or is there any workaround ?

Note : I dont want the text length that returns the number of characters in the string, instead the extent width of the string.
Thanks in Advance !!

Best Answer

Answers

  • JeffreyVoigtJeffreyVoigt USMember

    I also need to do this in Xamarin.Forms. I have an absolute layout that I store labels in. I need them to go at specific locations which requires me to get the width/height at runtime based on the text/Font. How can this be achieved? Something similar to the graphics.MeasureString would be optimal.

  • TonyDTonyD USMember ✭✭✭

    @JeffreyVoigt you can override the Measure function of the parent layout (create a custom layout similar to AbsoluteLayout) and call measure for the individual labels in that phase. However, that might be overkill depending on what exactly you're trying to achieve.

  • JohnHardmanJohnHardman GBUniversity admin

    I have a similar requirement. I have a number of fixed-size Views on a row, but in the space remaining what to put a timer (as a Label) in HH:MM:SS format. If the screen width cannot fit the whole of that in, I want it to fallback to just HH:MM , or even just HH if it cannot fit HH:MM in.

    Given a FontFamily, FontSize and FontAttributes, I'd be after a method that calculates the horizontal text extent for the text that would go in a particular View (most important being a Label, but it would be good if it worked for Button too).

    I do have workarounds for my particular scenario, but a method that gets the horizontal text extent, that works across platforms, would be the ideal.

    An alternative (which I know Xamarin have been asked for previously) is to have an API that specifies that the FontSize should be set automatically such that the specified Text fits within the Width available using the largest font that results in the text fitting.

  • JohnHardmanJohnHardman GBUniversity admin

    @Vimal.4745 - Many thanks. When I have time, I'll tweak it so that this uses a FontSize that is passed in, rather than a hard-coded size, but this is a great starting point.

  • HabibAli_SubhanHabibAli_Subhan PKMember ✭✭

    WinRT IMPLEMENTATION
    public double calculateWidth(string text) { var textBlock = new TextBlock() { FontSize = 12 }; textBlock.Text = text; var parentBorder = new Border { Child = textBlock }; textBlock.MaxHeight = 50; textBlock.MaxWidth = double.PositiveInfinity; parentBorder.Measure(new System.Windows.Size(textBlock.MaxWidth, textBlock.MaxHeight)); parentBorder.Child = null; return parentBorder.DesiredSize.Width; }

    Please leave a comment in case of any queries

    Regards,
    Vimal Prabhu

    Thanks Vimal but I am facing some problems in implementing that function. Some how the function is not returning correct values for height. It is always returning height for one line unless there is carriage return in the text. I have implemented it like this

    private int MeasureTextSize(string text, double width,Xamarin.Forms.Font font)
            {
                var textBlock = new TextBlock();
                textBlock.ApplyFont(font);
                textBlock.Text = text;
                var parentBorder = new Border { Child = textBlock };
                textBlock.MaxHeight = double.PositiveInfinity;
                textBlock.MaxWidth = width;
                parentBorder.Measure(new Size(textBlock.MaxWidth, textBlock.MaxHeight));
                parentBorder.Child = null;
                return (int)parentBorder.DesiredSize.Height;
    
            }
    

    Can you please help

  • HabibAli_SubhanHabibAli_Subhan PKMember ✭✭

    WinRT IMPLEMENTATION
    public double calculateWidth(string text) { var textBlock = new TextBlock() { FontSize = 12 }; textBlock.Text = text; var parentBorder = new Border { Child = textBlock }; textBlock.MaxHeight = 50; textBlock.MaxWidth = double.PositiveInfinity; parentBorder.Measure(new System.Windows.Size(textBlock.MaxWidth, textBlock.MaxHeight)); parentBorder.Child = null; return parentBorder.DesiredSize.Width; }

    Thanks Vimal. I have implemented your code in windows RT but I am facing some problems in getting the desired results for height. I have implemented this code

    private int MeasureTextSize(string text, double width,Xamarin.Forms.Font font)
            {
                var textBlock = new TextBlock();
                textBlock.ApplyFont(font);
                textBlock.Text = text;
                var parentBorder = new Border { Child = textBlock };
                textBlock.MaxHeight = double.PositiveInfinity;
                textBlock.MaxWidth = width;
                parentBorder.Measure(new Size(textBlock.MaxWidth, textBlock.MaxHeight));
                parentBorder.Child = null;
                return (int)parentBorder.DesiredSize.Height;
    
            }
    

    I am not getting correct height. I am always getting height for one line unless there is carriage return in the text

  • HabibAli_SubhanHabibAli_Subhan PKMember ✭✭

    @HabibAli_Subhan said:

    WinRT IMPLEMENTATION
    public double calculateWidth(string text) { var textBlock = new TextBlock() { FontSize = 12 }; textBlock.Text = text; var parentBorder = new Border { Child = textBlock }; textBlock.MaxHeight = 50; textBlock.MaxWidth = double.PositiveInfinity; parentBorder.Measure(new System.Windows.Size(textBlock.MaxWidth, textBlock.MaxHeight)); parentBorder.Child = null; return parentBorder.DesiredSize.Width; }

    Thanks Vimal. I have implemented your code in windows RT but I am facing some problems in getting the desired results for height. I have implemented this code

    private int MeasureTextSize(string text, double width,Xamarin.Forms.Font font)
            {
                var textBlock = new TextBlock();
                textBlock.ApplyFont(font);
                textBlock.Text = text;
                var parentBorder = new Border { Child = textBlock };
                textBlock.MaxHeight = double.PositiveInfinity;
                textBlock.MaxWidth = width;
                parentBorder.Measure(new Size(textBlock.MaxWidth, textBlock.MaxHeight));
                parentBorder.Child = null;
                return (int)parentBorder.DesiredSize.Height;
             
            }
    

    I am not getting correct height. I am always getting height for one line unless there is carriage return in the text

    Problem resolved just insert
    textBlocktb.TextWrapping = TextWrapping.Wrap;

  • naychithwaenaychithwae USMember

    I want to know how to measure textview height .Please answer to me.

  • njsokalskinjsokalski Member ✭✭✭

    I like @Vimal.4745's answer, but there are several things I am having trouble figuring out how to do. First, I need to calculate the size in the Xamarin.Forms project, but I need a TextView in your method. This makes since, and I understand why, but I would like to know if there is a way to use the Renderer to convert my Label to a TextView to be used in the measurer (so that I do not need to manually set all the properties by hand)? My Label(s) use Style(s) which are located in my Xamarin.Forms project, and the Style(s) obviously target Label(s) (not TextView(s)) I think my basic question is how do I use your code from my Xamarin.Forms project? Thanks.

Sign In or Register to comment.