Bug 59935 - Grid Misbehavior?
Summary: Grid Misbehavior?
Status: RESOLVED ANSWERED
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms (show other bugs)
Version: 2.4.0
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2017-10-03 18:31 UTC by Daniel Robbins
Modified: 2017-10-03 22:24 UTC (History)
2 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED ANSWERED

Description Daniel Robbins 2017-10-03 18:31:48 UTC
Using Xamarin Forms 2.4.0.282.

I am creating what appears to be a relatively simple Grid, which has one column and three rows:

this._grid = new Grid
            {
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                RowDefinitions =
                {
                    new RowDefinition { Height = new GridLength(7, GridUnitType.Star) },
                    new RowDefinition { Height = new GridLength(3, GridUnitType.Star) },
                    new RowDefinition { Height = new GridLength(30, GridUnitType.Absolute) }
                },
                ColumnDefinitions =
                {
                    new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }
                },
                RowSpacing = 0,
                ColumnSpacing = 0
            };

When I try to add elements to the grid, it appears that Forms is doing incorrect bounds checking, or something else is wonky. Specifically, I get an System.ArgumentOutOfRange exception when I shouldn't. The thing to note below is that because I have three rows, it should be possible for me to create something with a start row of zero and and end row (rowspan) of 2. This would make the element I'm adding span all three rows -- from row zero to row 2. It should be legal, and yet it's not.

For example, using the template this._grid.Children.Add(obj, row, rowspan, col, colspan) I set System.ArgumentOutOfRange exception (parameter 'bottom') using the following values:

        _grid.Children.Add(_map, 0, 1, 0, 2); // add map to all rows (start row 0, end row 2)
        _grid.Children.Add(_slidein_layout, 0, 1, 0, 2); // add slidein_layout to all rows (start row 0, end row 2)
        _grid.Children.Add(_static_layout, 0, 1, 1, 1); // add static_layout to middle row only (start row 1, end row 1)

I have tried setting the row/colspan values to 0 to see if that works, and it does not. I have also tried swapping the row/column settings and that doesn't work. The following gives me an out-of-range exception as well (on parameter 'left):

        _grid.Children.Add(_map, 0, 2, 0, 1);
        _grid.Children.Add(_slidein_layout, 0, 2, 0, 1);
        _grid.Children.Add(_static_layout, 1, 1, 0, 1);

I do believe the first set of _grid_Children.Add() calls should work with no issue and this is a bug.
Comment 1 E.Z. Hart [MSFT] 2017-10-03 20:34:10 UTC
Daniel,

Based on your code comments, I think you may be running into an off-by-one error. The column/row referred to by the `right` and `bottom` parameters are non-inclusive; in other words, take the rightmost/bottommost column/row you'd like the View to cover and then add 1. 

So the code you posted:
_grid.Children.Add(_map, 0, 1, 0, 2); // add map to all rows (start row 0, end row 2)
_grid.Children.Add(_slidein_layout, 0, 1, 0, 2); // add slidein_layout to all rows (start row 0, end row 2)
_grid.Children.Add(_static_layout, 0, 1, 1, 1); // add static_layout to middle row only (start row 1, end row 1)

Should be:
_grid.Children.Add(_map, 0, 1, 0, 3); // add map to all rows (start row 0, end row 2)
_grid.Children.Add(_slidein_layout, 0, 1, 0, 3); // add slidein_layout to all rows (start row 0, end row 2)
_grid.Children.Add(_static_layout, 0, 1, 1, 2); // add static_layout to middle row only (start row 1, end row 1)

For more context, you may want to take a look at the source for the method: https://github.com/xamarin/Xamarin.Forms/blob/210df5f775b2aa682b2c823f1d854d8290e46e27/Xamarin.Forms.Core/Grid.cs#L309
Comment 2 Daniel Robbins 2017-10-03 22:24:43 UTC
OK, thanks, I have created some feedback for the doc team to make this non-inclusive behavior VERY CLEAR on https://developer.xamarin.com/guides/xamarin-forms/user-interface/layouts/grid/ as it is non-intuitive and I would expect it to continue to trip up new developers.