/// <summary> /// Arranges the content of the <see cref="DataGridRowsPresenter"/>. /// </summary> /// <returns> /// The actual size used by the <see cref="DataGridRowsPresenter"/>. /// </returns> /// <param name="finalSize"> /// The final area within the parent that this element should use to arrange itself and its children. /// </param> protected override Size ArrangeOverride(Size finalSize) { if (finalSize.Height == 0 || this.OwningGrid == null) { return(base.ArrangeOverride(finalSize)); } this.OwningGrid.OnFillerColumnWidthNeeded(finalSize.Width); double rowDesiredWidth = this.OwningGrid.ColumnsInternal.VisibleEdgedColumnsWidth + this.OwningGrid.ColumnsInternal.FillerColumn.FillerWidth; double topEdge = -this.OwningGrid.NegVerticalOffset; foreach (UIElement element in this.OwningGrid.DisplayData.GetScrollingElements()) { DataGridRow row = element as DataGridRow; if (row != null) { DiagnosticsDebug.Assert(row.Index != -1, "Expected Index other than -1."); // A displayed row should always have its index // Visibility for all filler cells needs to be set in one place. Setting it individually in // each CellsPresenter causes an NxN layout cycle (see DevDiv Bugs 211557) row.EnsureFillerVisibility(); row.Arrange(new Rect(-this.OwningGrid.HorizontalOffset, topEdge, rowDesiredWidth, element.DesiredSize.Height)); } else { DataGridRowGroupHeader groupHeader = element as DataGridRowGroupHeader; if (groupHeader != null) { double leftEdge = this.OwningGrid.AreRowGroupHeadersFrozen ? 0 : -this.OwningGrid.HorizontalOffset; groupHeader.Arrange(new Rect(leftEdge, topEdge, rowDesiredWidth - leftEdge, element.DesiredSize.Height)); } } topEdge += element.DesiredSize.Height; } double finalHeight = Math.Max(topEdge + this.OwningGrid.NegVerticalOffset, finalSize.Height); // Clip the RowsPresenter so rows cannot overlap other elements in certain styling scenarios RectangleGeometry rg = new RectangleGeometry(); rg.Rect = new Rect(0, 0, finalSize.Width, finalHeight); this.Clip = rg; return(new Size(finalSize.Width, finalHeight)); }