Ejemplo n.º 1
0
        /// <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));
        }