How to measure the size of a control in code

1 Answer 2241 Views
NumericInput
Harald Bacik
Top achievements
Rank 2
Harald Bacik asked on 08 Jan 2022, 02:55 PM

Hey

I try to measure the size of a control, when I prefill it with values.
Therefor, I tested with the Microsoft Edit Control, which gives me the correct value, when I do the following code snipset:
   

            Editor locEditor = new();
            locEditor.Text = "TEST";
            locEditor.FontFamily = this.FontFamily;
            locEditor.FontSize = this.FontSize;
            locEditor.ToNative(this.Handler.MauiContext);
            var locSize = locEditor.Handler.GetDesiredSize(double.PositiveInfinity, double.PositiveInfinity);
            locEditor = null;
Variable locSize has the height and width of the control

RadNumericMaskedEntry locEditor = new();
            locEditor.Value = "TEST";
            locEditor.Handler = this.Handler;
            // - Not working: var locSize = locEditor.Handler.GetDesiredSize(double.PositiveInfinity, double.PositiveInfinity);
            // - Not working: var locSize = locEditor.CrossPlatformMeasure(double.PositiveInfinity, double.PositiveInfinity);
            //- Not working:  var locSize = locEditor.Measure(double.PositiveInfinity, double.PositiveInfinity).Request;
            locEditor = null;
           

 

But when I try to use the RadNumeric, the size always returns 0


What could this be? 

THX a lot in advance



Antoan
Telerik team
commented on 10 Jan 2022, 03:40 PM

Hi, Harald

It seems I cannot reproduce your case due to insufficient information.

Could you provide more information about the Handler's value, so we can get a better understanding of the issue.

 

Regards,
Antoan
Progress Telerik

 
Harald Bacik
Top achievements
Rank 2
commented on 10 Jan 2022, 06:40 PM

Hey

I try to Create an Extension like this:

The idea behind it, is that the width should not be greater, than a specific text / value.

namespaceTelerikMaui.ControlExtensions { publicclassISNumericInput:RadNumericMaskedEntry { public ISNumericInput() { Telerik.Maui.Handlers.RadNumericMaskedEntryHandler.ViewMapper.AppendToMapping(nameof(IViewHandler), (handler, control) => { if (control is ISNumericInput) { this.Handler = handler; this.SetControlWidth(TextMeasurement); } }); private void SetControlWidth(TypeOfTextMeasurement typeOfTextMeasurement) { RadNumericMaskedEntry locEditor = new(); locEditor.Value = 99; locEditor.Handler = this.Handler; locEditor.Unfocus(); //var locSize = locEditor.Handler.GetDesiredSize(double.PositiveInfinity, double.PositiveInfinity);//var locSize = locEditor.CrossPlatformMeasure(double.PositiveInfinity, double.PositiveInfinity);//locSize = locEditor.Measure(double.PositiveInfinity, double.PositiveInfinity).Request; tocEditor = null; this.MinimumHeightRequest = locSize.Height; this.MaximumHeightRequest = locSize.Height; this.MinimumWidthRequest = locSize.Width; this.MaximumWidthRequest = locSize.Width; this.WidthRequest = locSize.Width; this.HeightRequest = locSize.Height; } } } }

 

1 Answer, 1 is accepted

Sort by
1
Antoan
Telerik team
answered on 13 Jan 2022, 01:24 PM

Hi Harald,

Thank you for providing more details. 

We created a project and used test code that is very similar to yours. Then we tried to measure the mask control and we got the following results: we received properly desired-sizes for the mask in Android and iOS but on WinUI, the size is always 0.

RadNumericMaskedEntry locEditor = new();
locEditor.Value = 5555;
locEditor.ToNative(this.Handler.MauiContext);
var locSize = locEditor.Handler.GetDesiredSize(double.PositiveInfinity, double.PositiveInfinity);

Our components are not designed to be measured when the above setup is used. For instance implicit styles may be needed for the control to properly load. In general, a control should be added to the visual tree in order to be ready for "measure". We are not sure for a concrete reason why this works on Android and iOS (again, we have never specifically designed them to work in this case, they just happen to work), and doesn't work on Windows (perhaps the ControlTemplate of the native control has not been applied yet). 

We tested the provided code for the Editor and on Windows - the control is not measured correctly. In Android and iOS it does work, but again - I think that it just happens to work. I don't think that it is by design.

Solution:

In order to measure the size of the NumericMasked control, the control have to be added to the Visual Tree. Then the Measure() method of the control returns meaningful values in all platforms. 

Use the following code in your project:

RadNumericMaskedEntry nme = new RadNumericMaskedEntry();
nme.Value = 12345;
this.gridPanel.Children.Add(nme);
var result = nme.Measure(double.PositiveInfinity, double.PositiveInfinity);
this.gridPanel.Children.Remove(nme);

Note that here the Handlers are not reused. By design, every element in .NET MAUI receives its own Handler after being added to the Visual Tree.

I hope the provided information and solution will be of help. If you have any additional questions on this, please share more details about the exact requirements you have. Once we have all the details, we can check whether a different solution can be provided.

Regards,
Antoan
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Jamison
Top achievements
Rank 1
Iron
commented on 10 Nov 2023, 01:07 PM

Hey Antoan,

Calling Measure() method works fine in my side when I want to know the size of the control in events like loaded, ChildAdded, SizeChanged, etc. where I can't read from Width property directly since the control has't rendered yet so Width always return -1 or NaN.

But I just wondering is width returned from Measure() method always equals to the Width property value after the control was rendered probably in the UI?

Regards,

Jamison Jia.

 

Yana
Telerik team
commented on 14 Nov 2023, 02:31 PM

Hi Jia,

The short answer is no, you cannot always  rely on the Measure() method to receive the same Width after the control was rendered as this depends on the layout as well. Measure method will give you the needed size for the control depending on the set constraints,  still after that within the Arrange the real size is determined when the control is positioned in the layout.

 

Tags
NumericInput
Asked by
Harald Bacik
Top achievements
Rank 2
Answers by
Antoan
Telerik team
Share this question
or