private void ResizeRows(Grid grid, double deltaX) { GridResizeBehavior effectiveGridResizeBehavior = this.DetermineEffectiveResizeBehavior(); int row = Grid.GetRow(this); int upperRow; int lowerRow; switch (effectiveGridResizeBehavior) { case GridResizeBehavior.PreviousAndCurrent: upperRow = row - 1; lowerRow = row; break; case GridResizeBehavior.PreviousAndNext: upperRow = row - 1; lowerRow = row + 1; break; default: upperRow = row; lowerRow = row + 1; break; } if (lowerRow >= grid.RowDefinitions.Count) { return; } var upperRowDefinition = grid.RowDefinitions[upperRow]; var lowerRowDefinition = grid.RowDefinitions[lowerRow]; var upperRowGridUnitType = upperRowDefinition.Height.GridUnitType; var lowerRowGridUnitType = lowerRowDefinition.Height.GridUnitType; var upperRowActualHeight = upperRowDefinition.ActualHeight; var lowerRowActualHeight = lowerRowDefinition.ActualHeight; var upperRowMaxHeight = upperRowDefinition.MaxHeight; var lowerRowMaxHeight = lowerRowDefinition.MaxHeight; var upperRowMinHeight = upperRowDefinition.MinHeight; var lowerRowMinHeight = lowerRowDefinition.MinHeight; //deltaX = 200; if (upperRowActualHeight + deltaX > upperRowMaxHeight) { deltaX = Math.Max( 0, upperRowDefinition.MaxHeight - upperRowActualHeight); } if (upperRowActualHeight + deltaX < upperRowMinHeight) { deltaX = Math.Min( 0, upperRowDefinition.MinHeight - upperRowActualHeight); } if (lowerRowActualHeight - deltaX > lowerRowMaxHeight) { deltaX = -Math.Max( 0, lowerRowDefinition.MaxHeight - lowerRowActualHeight); } if (lowerRowActualHeight - deltaX < lowerRowMinHeight) { deltaX = -Math.Min( 0, lowerRowDefinition.MinHeight - lowerRowActualHeight); } var newUpperRowActualHeight = upperRowActualHeight + deltaX; var newLowerRowActualHeight = lowerRowActualHeight - deltaX; grid.BeginInit(); double totalStarRowsHeight = 0; double starRowsAvailableHeight = grid.ActualHeight; if (upperRowGridUnitType == GridUnitType.Star || lowerRowGridUnitType == GridUnitType.Star) { foreach (var rowDefinition in grid.RowDefinitions) { if (rowDefinition.Height.GridUnitType == GridUnitType.Star) { totalStarRowsHeight += rowDefinition.Height.Value; } else { starRowsAvailableHeight -= rowDefinition.ActualHeight; } } } if (upperRowGridUnitType == GridUnitType.Star) { if (lowerRowGridUnitType == GridUnitType.Star) { // If both rows are star rows // - totalStarRowsHeight won't change and // as much as one of the rows grows // - the other row will shrink by the same value. // If there is no width available to star rows // - we can't resize two of them. if (starRowsAvailableHeight < 1) { return; } var oldStarHeight = upperRowDefinition.Height.Value; var newStarHeight = Math.Max( 0, totalStarRowsHeight * newUpperRowActualHeight / starRowsAvailableHeight); upperRowDefinition.Height = new GridLength(newStarHeight, GridUnitType.Star); lowerRowDefinition.Height = new GridLength( Math.Max( 0, lowerRowDefinition.Height.Value - newStarHeight + oldStarHeight), GridUnitType.Star); } else { var newStarRowsAvailableHeight = starRowsAvailableHeight + lowerRowActualHeight - newLowerRowActualHeight; if (newStarRowsAvailableHeight - newUpperRowActualHeight >= 1) { var newStarHeight = Math.Max( 0, (totalStarRowsHeight - upperRowDefinition.Height.Value) * newUpperRowActualHeight / (newStarRowsAvailableHeight - newUpperRowActualHeight)); upperRowDefinition.Height = new GridLength(newStarHeight, GridUnitType.Star); } } } else { upperRowDefinition.Height = new GridLength( newUpperRowActualHeight, GridUnitType.Pixel); } if (lowerRowGridUnitType == GridUnitType.Star) { if (upperRowGridUnitType != GridUnitType.Star) { var newStarRowsAvailableHeight = starRowsAvailableHeight + upperRowActualHeight - newUpperRowActualHeight; if (newStarRowsAvailableHeight - newLowerRowActualHeight >= 1) { var newStarHeight = Math.Max( 0, (totalStarRowsHeight - lowerRowDefinition.Height.Value) * newLowerRowActualHeight / (newStarRowsAvailableHeight - newLowerRowActualHeight)); lowerRowDefinition.Height = new GridLength(newStarHeight, GridUnitType.Star); } } // else handled in the upper row width calculation block } else { lowerRowDefinition.Height = new GridLength( newLowerRowActualHeight, GridUnitType.Pixel); } grid.EndInit(); }
private void ResizeColumns(Grid grid, double deltaX) { GridResizeBehavior effectiveGridResizeBehavior = this.DetermineEffectiveResizeBehavior(); int column = Grid.GetColumn(this); int leftColumn; int rightColumn; switch (effectiveGridResizeBehavior) { case GridResizeBehavior.PreviousAndCurrent: leftColumn = column - 1; rightColumn = column; break; case GridResizeBehavior.PreviousAndNext: leftColumn = column - 1; rightColumn = column + 1; break; default: leftColumn = column; rightColumn = column + 1; break; } if (rightColumn >= grid.ColumnDefinitions.Count) { return; } var leftColumnDefinition = grid.ColumnDefinitions[leftColumn]; var rightColumnDefinition = grid.ColumnDefinitions[rightColumn]; var leftColumnGridUnitType = leftColumnDefinition.Width.GridUnitType; var rightColumnGridUnitType = rightColumnDefinition.Width.GridUnitType; var leftColumnActualWidth = leftColumnDefinition.ActualWidth; var rightColumnActualWidth = rightColumnDefinition.ActualWidth; var leftColumnMaxWidth = leftColumnDefinition.MaxWidth; var rightColumnMaxWidth = rightColumnDefinition.MaxWidth; var leftColumnMinWidth = leftColumnDefinition.MinWidth; var rightColumnMinWidth = rightColumnDefinition.MinWidth; //deltaX = 200; if (leftColumnActualWidth + deltaX > leftColumnMaxWidth) { deltaX = Math.Max( 0, leftColumnDefinition.MaxWidth - leftColumnActualWidth); } if (leftColumnActualWidth + deltaX < leftColumnMinWidth) { deltaX = Math.Min( 0, leftColumnDefinition.MinWidth - leftColumnActualWidth); } if (rightColumnActualWidth - deltaX > rightColumnMaxWidth) { deltaX = -Math.Max( 0, rightColumnDefinition.MaxWidth - rightColumnActualWidth); } if (rightColumnActualWidth - deltaX < rightColumnMinWidth) { deltaX = -Math.Min( 0, rightColumnDefinition.MinWidth - rightColumnActualWidth); } var newLeftColumnActualWidth = leftColumnActualWidth + deltaX; var newRightColumnActualWidth = rightColumnActualWidth /* - deltaX*/; grid.BeginInit(); double totalStarColumnsWidth = 0; double starColumnsAvailableWidth = grid.ActualWidth; if (leftColumnGridUnitType == GridUnitType.Star || rightColumnGridUnitType == GridUnitType.Star) { foreach (var columnDefinition in grid.ColumnDefinitions) { if (columnDefinition.Width.GridUnitType == GridUnitType.Star) { totalStarColumnsWidth += columnDefinition.Width.Value; } else { starColumnsAvailableWidth -= columnDefinition.ActualWidth; } } } if (leftColumnGridUnitType == GridUnitType.Star) { if (rightColumnGridUnitType == GridUnitType.Star) { // If both columns are star columns // - totalStarColumnsWidth won't change and // as much as one of the columns grows // - the other column will shrink by the same value. // If there is no width available to star columns // - we can't resize two of them. if (starColumnsAvailableWidth < 1) { return; } var oldStarWidth = leftColumnDefinition.Width.Value; var newStarWidth = Math.Max( 0, totalStarColumnsWidth * newLeftColumnActualWidth / starColumnsAvailableWidth); leftColumnDefinition.Width = new GridLength(newStarWidth, GridUnitType.Star); rightColumnDefinition.Width = new GridLength( Math.Max( 0, rightColumnDefinition.Width.Value - newStarWidth + oldStarWidth), GridUnitType.Star); } else { var newStarColumnsAvailableWidth = starColumnsAvailableWidth + rightColumnActualWidth - newRightColumnActualWidth; if (newStarColumnsAvailableWidth - newLeftColumnActualWidth >= 1) { var newStarWidth = Math.Max( 0, (totalStarColumnsWidth - leftColumnDefinition.Width.Value) * newLeftColumnActualWidth / (newStarColumnsAvailableWidth - newLeftColumnActualWidth)); leftColumnDefinition.Width = new GridLength(newStarWidth, GridUnitType.Star); } } } else { leftColumnDefinition.Width = new GridLength( newLeftColumnActualWidth, GridUnitType.Pixel); } if (rightColumnGridUnitType == GridUnitType.Star) { if (leftColumnGridUnitType != GridUnitType.Star) { var newStarColumnsAvailableWidth = starColumnsAvailableWidth + leftColumnActualWidth - newLeftColumnActualWidth; if (newStarColumnsAvailableWidth - newRightColumnActualWidth >= 1) { var newStarWidth = Math.Max( 0, (totalStarColumnsWidth - rightColumnDefinition.Width.Value) * newRightColumnActualWidth / (newStarColumnsAvailableWidth - newRightColumnActualWidth)); rightColumnDefinition.Width = new GridLength(newStarWidth, GridUnitType.Star); } } // else handled in the left column width calculation block } else { rightColumnDefinition.Width = new GridLength( newRightColumnActualWidth, GridUnitType.Pixel); } grid.EndInit(); }