private void UpdateDefinitions(MetaElementStateDict stateDict,
ICollection elements,
bool spanning)
{
foreach (UIElement element in elements)
{
// Find the row/col definitions for this element
int col = Math.Max(0, Math.Min(_columns.Count - 1, GetColumn(element)));
int row = Math.Max(0, Math.Min(_rows.Count - 1, GetRow(element)));
// Find the row/col spanning definitions for this element (convert to zero based spanning)
int colSpan = Math.Max(Math.Min(_columns.Count - col, GetColumnSpan(element)), 1) - 1;
int rowSpan = Math.Max(Math.Min(_rows.Count - row, GetRowSpan(element)), 1) - 1;
// If cell covers a single column then update the minimum size of column with desired width
if (!spanning && (colSpan == 0))
_proxyColumns[col].UpdateFromMeasure(stateDict[element].Element.DesiredSize.Width);
if (spanning && (colSpan > 0))
{
// Quantity of desired width to be allocated
double desiredWidth = stateDict[element].Element.DesiredSize.Width;
// Scan all spanning columns and remove the already allocated space from desired width
int index = col;
int autoColumns = 0;
do
{
desiredWidth -= _proxyColumns[index].MinSize;
if (_proxyColumns[index].UserGridUnitType == GridUnitType.Auto)
autoColumns++;
} while (index++ < (col + colSpan));
// If there is still some width left to allocate and something to allocate into
if ((desiredWidth > 0) && (autoColumns > 0))
{
index = col;
do
{
if (_proxyColumns[index].UserGridUnitType == GridUnitType.Auto)
{
double extraSpace = desiredWidth / autoColumns--;
desiredWidth -= extraSpace;
_proxyColumns[index].UpdateFromMeasure(_proxyColumns[index].MinSize + extraSpace);
}
} while (index++ < (col + colSpan));
}
}
// If cell covers a single row then update the minimum size of column with desired height
if (!spanning & (rowSpan == 0))
_proxyRows[row].UpdateFromMeasure(stateDict[element].Element.DesiredSize.Height);
if (spanning && (rowSpan > 0))
{
// Quantity of desired height to be allocated
double desiredHeight = stateDict[element].Element.DesiredSize.Height;
// Scan all spanning columns and remove the already allocated space from desired height
int index = col;
int autoRows = 0;
do
{
desiredHeight -= _proxyColumns[index].MinSize;
if (_proxyColumns[index].UserGridUnitType == GridUnitType.Auto)
autoRows++;
} while (index++ < (col + colSpan));
// If there is still some height left to allocate and something to allocate into
if ((desiredHeight > 0) && (autoRows > 0))
{
index = col;
do
{
if (_proxyColumns[index].UserGridUnitType == GridUnitType.Auto)
{
double extraSpace = desiredHeight / autoRows--;
desiredHeight -= extraSpace;
_proxyColumns[index].UpdateFromMeasure(_proxyColumns[index].MinSize + extraSpace);
}
} while (index++ < (col + colSpan));
}
}
}
}