示例#1
0
        /// <summary>
        /// Measures the children of a <see cref="DataGridColumnHeadersPresenter"/> 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="DataGridColumnHeadersPresenter"/> 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));
            }

            if (!this.OwningGrid.AreColumnHeadersVisible)
            {
                return(new Size(0.0, 0.0));
            }

            double height = this.OwningGrid.ColumnHeaderHeight;
            bool   autoSizeHeight;

            if (double.IsNaN(height))
            {
                // No explicit height values were set so we can autosize
                height         = 0;
                autoSizeHeight = true;
            }
            else
            {
                autoSizeHeight = false;
            }

            double totalDisplayWidth = 0;

            this.OwningGrid.ColumnsInternal.EnsureVisibleEdgedColumnsWidth();
            DataGridColumn lastVisibleColumn = this.OwningGrid.ColumnsInternal.LastVisibleColumn;

            foreach (DataGridColumn column in this.OwningGrid.ColumnsInternal.GetVisibleColumns())
            {
                // Measure each column header
                bool autoGrowWidth = column.Width.IsAuto || column.Width.IsSizeToHeader;
                DataGridColumnHeader columnHeader = column.HeaderCell;
                if (column != lastVisibleColumn)
                {
                    columnHeader.UpdateSeparatorVisibility(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 header content, we want to measure it at its maximum value
                if (autoGrowWidth)
                {
                    columnHeader.Measure(new Size(column.ActualMaxWidth, double.PositiveInfinity));
                    this.OwningGrid.AutoSizeColumn(column, columnHeader.DesiredSize.Width);
                    column.ComputeLayoutRoundedWidth(totalDisplayWidth);
                }
                else if (!this.OwningGrid.UsesStarSizing)
                {
                    column.ComputeLayoutRoundedWidth(totalDisplayWidth);
                    columnHeader.Measure(new Size(column.LayoutRoundedWidth, double.PositiveInfinity));
                }

                // We need to track the largest height in order to auto-size
                if (autoSizeHeight)
                {
                    height = Math.Max(height, columnHeader.DesiredSize.Height);
                }

                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 = double.IsPositiveInfinity(availableSize.Width) ? this.OwningGrid.CellsWidth : availableSize.Width - 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 header
                double leftEdge = 0;
                foreach (var column in this.OwningGrid.ColumnsInternal.GetVisibleColumns())
                {
                    column.ComputeLayoutRoundedWidth(leftEdge);
                    column.HeaderCell.Measure(new Size(column.LayoutRoundedWidth, double.PositiveInfinity));
                    if (autoSizeHeight)
                    {
                        height = Math.Max(height, column.HeaderCell.DesiredSize.Height);
                    }

                    leftEdge += column.ActualWidth;
                }
            }

            // Add the filler column if it's not represented.  We won't know whether we need it or not until Arrange
            DataGridFillerColumn fillerColumn = this.OwningGrid.ColumnsInternal.FillerColumn;

            if (!fillerColumn.IsRepresented)
            {
                DiagnosticsDebug.Assert(!this.Children.Contains(fillerColumn.HeaderCell), "Unexpected parent for filler column header cell.");
                fillerColumn.HeaderCell.SeparatorVisibility = Visibility.Collapsed;
                this.Children.Insert(this.OwningGrid.ColumnsInternal.Count, fillerColumn.HeaderCell);
                fillerColumn.IsRepresented = true;

                // Optimize for the case where we don't need the filler cell
                fillerColumn.HeaderCell.Visibility = Visibility.Collapsed;
            }

            fillerColumn.HeaderCell.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

            if (this.DragIndicator != null)
            {
                this.DragIndicator.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            }

            if (this.DropLocationIndicator != null)
            {
                this.DropLocationIndicator.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            }

            this.OwningGrid.ColumnsInternal.EnsureVisibleEdgedColumnsWidth();
            return(new Size(this.OwningGrid.ColumnsInternal.VisibleEdgedColumnsWidth, height));
        }
        private void OnPointerMove_BeginReorder(uint pointerId, Point pointerPosition)
        {
            Debug.Assert(this.OwningGrid != null, "Expected non-null OwningGrid.");

            DataGridColumnHeader dragIndicator = new DataGridColumnHeader();

            dragIndicator.OwningColumn    = this.OwningColumn;
            dragIndicator.IsEnabled       = false;
            dragIndicator.Content         = this.Content;
            dragIndicator.ContentTemplate = this.ContentTemplate;

            Control dropLocationIndicator = new ContentControl();

            dropLocationIndicator.SetStyleWithType(this.OwningGrid.DropLocationIndicatorStyle);

            if (this.OwningColumn.DragIndicatorStyle != null)
            {
                dragIndicator.SetStyleWithType(this.OwningColumn.DragIndicatorStyle);
            }
            else if (this.OwningGrid.DragIndicatorStyle != null)
            {
                dragIndicator.SetStyleWithType(this.OwningGrid.DragIndicatorStyle);
            }

            // If the user didn't style the dragIndicator's Width, default it to the column header's width.
            if (double.IsNaN(dragIndicator.Width))
            {
                dragIndicator.Width = this.ActualWidth;
            }

            // If the user didn't style the dropLocationIndicator's Height, default to the column header's height.
            if (double.IsNaN(dropLocationIndicator.Height))
            {
                dropLocationIndicator.Height = this.ActualHeight;
            }

            // pass the caret's data template to the user for modification.
            DataGridColumnReorderingEventArgs columnReorderingEventArgs = new DataGridColumnReorderingEventArgs(this.OwningColumn)
            {
                DropLocationIndicator = dropLocationIndicator,
                DragIndicator         = dragIndicator
            };

            this.OwningGrid.OnColumnReordering(columnReorderingEventArgs);
            if (columnReorderingEventArgs.Cancel)
            {
                return;
            }

            DataGridColumnHeaderInteractionInfo interactionInfo = this.OwningGrid.ColumnHeaderInteractionInfo;

            // The app didn't cancel, so prepare for the reorder.
            interactionInfo.DragColumn = this.OwningColumn;
            Debug.Assert(interactionInfo.DragMode != DragMode.None, "Expected _dragMode other than None.");
            interactionInfo.DragMode      = DragMode.Reorder;
            interactionInfo.DragPointerId = pointerId;
            interactionInfo.DragStart     = pointerPosition;

            // Display the reordering thumb.
            this.OwningGrid.ColumnHeaders.DragColumn            = this.OwningColumn;
            this.OwningGrid.ColumnHeaders.DragIndicator         = columnReorderingEventArgs.DragIndicator;
            this.OwningGrid.ColumnHeaders.DropLocationIndicator = columnReorderingEventArgs.DropLocationIndicator;
        }
示例#3
0
        /// <summary>
        /// Arranges the content of the <see cref="DataGridColumnHeadersPresenter"/>.
        /// </summary>
        /// <returns>
        /// The actual size used by the <see cref="DataGridColumnHeadersPresenter"/>.
        /// </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 (this.OwningGrid == null)
            {
                return(base.ArrangeOverride(finalSize));
            }

            if (this.OwningGrid.AutoSizingColumns)
            {
                // When we initially load an auto-column, we have to wait for all the rows to be measured
                // before we know its final desired size.  We need to trigger a new round of measures now
                // that the final sizes have been calculated.
                this.OwningGrid.AutoSizingColumns = false;
                return(base.ArrangeOverride(finalSize));
            }

            double dragIndicatorLeftEdge = 0;
            double frozenLeftEdge        = 0;
            double scrollingLeftEdge     = -this.OwningGrid.HorizontalOffset;

            foreach (DataGridColumn dataGridColumn in this.OwningGrid.ColumnsInternal.GetVisibleColumns())
            {
                DataGridColumnHeader columnHeader = dataGridColumn.HeaderCell;
                DiagnosticsDebug.Assert(columnHeader.OwningColumn == dataGridColumn, "Expected columnHeader owned by dataGridColumn.");

                if (dataGridColumn.IsFrozen)
                {
                    columnHeader.Arrange(new Rect(frozenLeftEdge, 0, dataGridColumn.LayoutRoundedWidth, finalSize.Height));
                    columnHeader.Clip = null; // The layout system could have clipped this because it's not aware of our render transform
                    if (this.DragColumn == dataGridColumn && this.DragIndicator != null)
                    {
                        dragIndicatorLeftEdge = frozenLeftEdge + this.DragIndicatorOffset;
                    }

                    frozenLeftEdge += dataGridColumn.ActualWidth;
                }
                else
                {
                    columnHeader.Arrange(new Rect(scrollingLeftEdge, 0, dataGridColumn.LayoutRoundedWidth, finalSize.Height));
                    EnsureColumnHeaderClip(columnHeader, dataGridColumn.ActualWidth, finalSize.Height, frozenLeftEdge, scrollingLeftEdge);
                    if (this.DragColumn == dataGridColumn && this.DragIndicator != null)
                    {
                        dragIndicatorLeftEdge = scrollingLeftEdge + this.DragIndicatorOffset;
                    }
                }

                scrollingLeftEdge += dataGridColumn.ActualWidth;
            }

            if (this.DragColumn != null)
            {
                if (this.DragIndicator != null)
                {
                    this.EnsureColumnReorderingClip(this.DragIndicator, finalSize.Height, frozenLeftEdge, dragIndicatorLeftEdge);
                    this.DragIndicator.Arrange(new Rect(dragIndicatorLeftEdge, 0, this.DragIndicator.ActualWidth, this.DragIndicator.ActualHeight));
                }

                if (this.DropLocationIndicator != null)
                {
                    this.EnsureColumnReorderingClip(this.DropLocationIndicator, finalSize.Height, frozenLeftEdge, this.DropLocationIndicatorOffset);
                    this.DropLocationIndicator.Arrange(new Rect(this.DropLocationIndicatorOffset, 0, this.DropLocationIndicator.ActualWidth, this.DropLocationIndicator.ActualHeight));
                }
            }

            // Arrange filler
            this.OwningGrid.OnFillerColumnWidthNeeded(finalSize.Width);
            DataGridFillerColumn fillerColumn = this.OwningGrid.ColumnsInternal.FillerColumn;

            if (fillerColumn.FillerWidth > 0)
            {
                fillerColumn.HeaderCell.Visibility = Visibility.Visible;
                fillerColumn.HeaderCell.Arrange(new Rect(scrollingLeftEdge, 0, fillerColumn.FillerWidth, finalSize.Height));
            }
            else
            {
                fillerColumn.HeaderCell.Visibility = Visibility.Collapsed;
            }

            // This needs to be updated after the filler column is configured
            DataGridColumn lastVisibleColumn = this.OwningGrid.ColumnsInternal.LastVisibleColumn;

            if (lastVisibleColumn != null)
            {
                lastVisibleColumn.HeaderCell.UpdateSeparatorVisibility(lastVisibleColumn);
            }

            return(finalSize);
        }