private (IDisposable Subscription, Memory <ViewPosition> Views) GetPositions(int numberOfColumns, int numberOfRows)
{
var refs = Children.SelectToArray(c => (View: c, Handle: GCHandle.Alloc(c, GCHandleType.Normal)));
return(
Disposable.Create(() => refs.ForEach(c => c.Handle.Free())),
refs
.SelectToMemory(c =>
{
return MapViewToGridPosition(c);
})
);
ViewPosition MapViewToGridPosition((View View, GCHandle Handle) c)
{
var column = Grid.GetColumn(c.View);
var columnSpan = Grid.GetColumnSpan(c.View);
if (column == 0)
{
// Ok: nothing to check
}
else if (column < 0)
{
column = 0;
}
else if (column >= numberOfColumns)
{
column = numberOfColumns - 1;
}
if (columnSpan == 1)
{
// Ok: nothing to check
}
else if (columnSpan < 1)
{
columnSpan = 1;
}
else if (column + columnSpan > numberOfColumns)
{
columnSpan = numberOfColumns - column;
}
var row = Grid.GetRow(c.View);
var rowSpan = Grid.GetRowSpan(c.View);
if (row == 0)
{
// Ok: nothing to check
}
else if (row < 0)
{
row = 0;
}
else if (row >= numberOfRows)
{
row = numberOfRows - 1;
}
if (rowSpan == 1)
{
// Ok: nothing to check
}
else if (rowSpan < 1)
{
rowSpan = 1;
}
else if (row + rowSpan > numberOfRows)
{
rowSpan = numberOfRows - row;
}
return(new ViewPosition(
c.Handle,
new GridPosition(
column,
row,
columnSpan,
rowSpan
)
));
}
}