/// <summary> /// Measures the children of a <see cref="T:System.Windows.Controls.Primitives.DataGridCellsPresenter"/> to /// prepare for arranging them during the <see cref="M:System.Windows.FrameworkElement.ArrangeOverride(System.Windows.Size)"/> pass. /// </summary> /// <param name="availableSize"> /// The available size that this element can give to child elements. Indicates an upper limit that child elements should not exceed. /// </param> /// <returns> /// The size that the <see cref="T:System.Windows.Controls.Primitives.DataGridCellsPresenter"/> determines it needs during layout, based on its calculations of child object allocated sizes. /// </returns> protected override Size MeasureOverride(Size availableSize) { if (this.OwningGrid == null) { return(base.MeasureOverride(availableSize)); } bool autoSizeHeight; double measureHeight; if (double.IsNaN(this.OwningGrid.RowHeight)) { // No explicit height values were set so we can autosize autoSizeHeight = true; measureHeight = double.PositiveInfinity; } else { this.DesiredHeight = this.OwningGrid.RowHeight; measureHeight = this.DesiredHeight; autoSizeHeight = false; } double frozenLeftEdge = 0; double totalDisplayWidth = 0; double scrollingLeftEdge = -this.OwningGrid.HorizontalOffset; this.OwningGrid.ColumnsInternal.EnsureVisibleEdgedColumnsWidth(); DataGridColumn lastVisibleColumn = this.OwningGrid.ColumnsInternal.LastVisibleColumn; foreach (DataGridColumn column in this.OwningGrid.ColumnsInternal.GetVisibleColumns()) { DataGridCell cell = this.OwningRow.Cells[column.Index]; // Measure the entire first row to make the horizontal scrollbar more accurate bool shouldDisplayCell = ShouldDisplayCell(column, frozenLeftEdge, scrollingLeftEdge) || this.OwningRow.Index == 0; EnsureCellDisplay(cell, shouldDisplayCell); if (shouldDisplayCell) { DataGridLength columnWidth = column.Width; bool autoGrowWidth = columnWidth.IsSizeToCells || columnWidth.IsAuto; if (column != lastVisibleColumn) { cell.EnsureGridLine(lastVisibleColumn); } // If we're not using star sizing or the current column can't be resized, // then just set the display width according to the column's desired width if (!this.OwningGrid.UsesStarSizing || (!column.ActualCanUserResize && !column.Width.IsStar)) { // In the edge-case where we're given infinite width and we have star columns, the // star columns grow to their predefined limit of 10,000 (or their MaxWidth) double newDisplayWidth = column.Width.IsStar ? Math.Min(column.ActualMaxWidth, DataGrid.DATAGRID_maximumStarColumnWidth) : Math.Max(column.ActualMinWidth, Math.Min(column.ActualMaxWidth, column.Width.DesiredValue)); column.SetWidthDisplayValue(newDisplayWidth); } // If we're auto-growing the column based on the cell content, we want to measure it at its maximum value if (autoGrowWidth) { cell.Measure(new Size(column.ActualMaxWidth, measureHeight)); this.OwningGrid.AutoSizeColumn(column, cell.DesiredSize.Width); column.ComputeLayoutRoundedWidth(totalDisplayWidth); } else if (!this.OwningGrid.UsesStarSizing) { column.ComputeLayoutRoundedWidth(scrollingLeftEdge); cell.Measure(new Size(column.LayoutRoundedWidth, measureHeight)); } // We need to track the largest height in order to auto-size if (autoSizeHeight) { this.DesiredHeight = Math.Max(this.DesiredHeight, cell.DesiredSize.Height); } } if (column.IsFrozen) { frozenLeftEdge += column.ActualWidth; } scrollingLeftEdge += column.ActualWidth; totalDisplayWidth += column.ActualWidth; } // If we're using star sizing (and we're not waiting for an auto-column to finish growing) // then we will resize all the columns to fit the available space. if (this.OwningGrid.UsesStarSizing && !this.OwningGrid.AutoSizingColumns) { double adjustment = this.OwningGrid.CellsWidth - totalDisplayWidth; this.OwningGrid.AdjustColumnWidths(0, adjustment, false); // Since we didn't know the final widths of the columns until we resized, // we waited until now to measure each cell double leftEdge = 0; foreach (DataGridColumn column in this.OwningGrid.ColumnsInternal.GetVisibleColumns()) { DataGridCell cell = this.OwningRow.Cells[column.Index]; column.ComputeLayoutRoundedWidth(leftEdge); cell.Measure(new Size(column.LayoutRoundedWidth, measureHeight)); if (autoSizeHeight) { this.DesiredHeight = Math.Max(this.DesiredHeight, cell.DesiredSize.Height); } leftEdge += column.ActualWidth; } } // Measure FillerCell, we're doing it unconditionally here because we don't know if we'll need the filler // column and we don't want to cause another Measure if we do this.OwningRow.FillerCell.Measure(new Size(double.PositiveInfinity, this.DesiredHeight)); this.OwningGrid.ColumnsInternal.EnsureVisibleEdgedColumnsWidth(); return(new Size(this.OwningGrid.ColumnsInternal.VisibleEdgedColumnsWidth, this.DesiredHeight)); }
/// <summary> /// Measures the children of a <see cref="T:System.Windows.Controls.Primitives.DataGridCellsPresenter" /> to /// prepare for arranging them during the <see cref="M:System.Windows.FrameworkElement.ArrangeOverride(System.Windows.Size)" /> pass. /// </summary> /// <param name="availableSize"> /// The available size that this element can give to child elements. Indicates an upper limit that child elements should not exceed. /// </param> /// <returns> /// The size that the <see cref="T:System.Windows.Controls.Primitives.DataGridCellsPresenter" /> determines it needs during layout, based on its calculations of child object allocated sizes. /// </returns> protected override Size MeasureOverride(Size availableSize) { if (this.OwningGrid == null) { return(base.MeasureOverride(availableSize)); } bool autoSizeHeight; double measureHeight; if (double.IsNaN(this.OwningGrid.RowHeight)) { // No explicit height values were set so we can autosize autoSizeHeight = true; measureHeight = double.PositiveInfinity; } else { this.DesiredHeight = this.OwningGrid.RowHeight; measureHeight = this.DesiredHeight; autoSizeHeight = false; } DataGridColumn lastVisibleColumn = this.OwningGrid.ColumnsInternal.LastVisibleColumn; double totalCellsWidth = this.OwningGrid.ColumnsInternal.VisibleEdgedColumnsWidth; double measureWidth; double frozenLeftEdge = 0; double scrollingLeftEdge = -this.OwningGrid.HorizontalOffset; foreach (DataGridColumn column in this.OwningGrid.ColumnsInternal.GetVisibleColumns()) { DataGridCell cell = this.OwningRow.Cells[column.Index]; // Measure the entire first row to make the horizontal scrollbar more accurate bool shouldDisplayCell = ShouldDisplayCell(column, frozenLeftEdge, scrollingLeftEdge) || this.OwningRow.Index == 0; EnsureCellDisplay(cell, shouldDisplayCell); if (shouldDisplayCell) { DataGridLength columnWidth = column.EffectiveWidth; measureWidth = columnWidth.IsAbsolute ? column.ActualWidth : column.ActualMaxWidth; bool autoGrowWidth = columnWidth.IsSizeToCells || columnWidth.IsAuto; cell.Measure(new Size(measureWidth, measureHeight)); if (column != lastVisibleColumn) { cell.EnsureGridLine(lastVisibleColumn); } if (autoSizeHeight) { this.DesiredHeight = Math.Max(this.DesiredHeight, cell.DesiredSize.Height); } if (autoGrowWidth && cell.DesiredSize.Width > column.DesiredWidth) { column.DesiredWidth = cell.DesiredSize.Width; } } if (column.IsFrozen) { frozenLeftEdge += column.ActualWidth; } scrollingLeftEdge += column.ActualWidth; } // Measure FillerCell, we're doing it unconditionally here because we don't know if we'll need the filler // column and we don't want to cause another Measure if we do this.OwningRow.FillerCell.Measure(new Size(double.PositiveInfinity, this.DesiredHeight)); return(new Size(totalCellsWidth, this.DesiredHeight)); }