Search code examples
xamarinxamarin.formsxamarin.androidxamarin.iosonmeasure

Custom control takes full space while setting Height as Auto in row definition


I tried to return the same size in the OnMeasure method. If I set the RowDefinition value as auto for my custom control, the custom control renders in the next row definition space also.

The custom control renders in 3 and 4 rows and the 4th-row control not visible on the screen.

Sample: CustomControl sample

[Xaml]

<Grid ColumnDefinitions="*,0.3*" RowDefinitions="auto,200,auto,auto">
          <Button BackgroundColor="Blue" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" ></Button>
          <Button BackgroundColor="Green" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" ></Button>
      
          <local:MyBoxView  BackgroundColor="Red" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" />
           
          <Button Text="Button" BackgroundColor="Brown" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" />


     </Grid>

[C#]

public class MyBoxView : BoxView
{
    public MyBoxView()
    {



    }
    protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
    {
        return new SizeRequest(new Size(widthConstraint, heightConstraint));
    }
}

When I add the custom(MyBoxview) control inside grid view means working properly. Please provide any suggestions on this.


Solution

  • From BoxView Class,BoxView has a default size request of 40x40. So you don't need to override SizeRequest OnMeasure.

    please remove SizeRequest OnMeasure method, then you will get the same size boxview.

     public class MyBoxView : BoxView
    {
        public MyBoxView()
        {
    
        }
       
    }
    

    Update:

    The OnMeasure method may be called, depending upon where our MyBoxView is placed and depending upon constraints of any outer layout. For example, if the MyBoxView is within a Grid.Row and that Row height is “*” then OnMeasure is not called. OnMeasure is called when the outer layout is asking “how much space do you require?”. In the case of “*”, we can think of it more like “this is how much space you’ve got”.

    In cases where OnMeasure is called, the widthConstraint or heightConstaint might be set to infinity. For example, if the MyBoxView is within a StackLayout, the StackLayout, in portrait orientation, will have not constrain height, hence heightConstraint will by set to infinity. Likewise with a landscape orientation the widthConstraint will be set to infinity. Therefore, when you are calculating the SizeRequest to return from OnMeasure, you will need to handle infinity situations.

    This MyBoxView will take all the available width or height to create a square of layout space. Hence in a scenario where this layout in within a GridLayout with “Auto” sizing, the MyBoxView will just say it requires an equal width and height based upon the minimum of the two.

    So the best way is to set RowDefinitions height=value or set MyBoxView height directly.