/// <summary> /// Overrides the core measure logic for windows. /// </summary> /// <param name="availableSize">The available size.</param> /// <returns>The measured size.</returns> /// <remarks> /// The layout logic for top-level windows is different than for other controls because /// they don't have a parent, meaning that many layout properties handled by the default /// MeasureCore (such as margins and alignment) make no sense. /// </remarks> protected override Size MeasureCore(Size availableSize) { ApplyStyling(); ApplyTemplate(); var constraint = LayoutHelper.ApplyLayoutConstraints(this, availableSize); return(MeasureOverride(constraint)); }
/// <summary> /// Measures the children of a <see cref="T:Avalonia.Controls.Primitives.DataGridRowsPresenter" /> 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:Avalonia.Controls.Primitives.DataGridRowsPresenter" /> determines it needs during layout, based on its calculations of child object allocated sizes. /// </returns> protected override Size MeasureOverride(Size availableSize) { if (double.IsInfinity(availableSize.Height)) { if (VisualRoot is TopLevel topLevel) { double maxHeight = topLevel.IsArrangeValid ? topLevel.Bounds.Height : LayoutHelper.ApplyLayoutConstraints(topLevel, availableSize).Height; availableSize = availableSize.WithHeight(maxHeight); } } if (availableSize.Height == 0 || OwningGrid == null) { return(base.MeasureOverride(availableSize)); } // If the Width of our RowsPresenter changed then we need to invalidate our rows bool invalidateRows = (!OwningGrid.RowsPresenterAvailableSize.HasValue || availableSize.Width != OwningGrid.RowsPresenterAvailableSize.Value.Width) && !double.IsInfinity(availableSize.Width); // The DataGrid uses the RowsPresenter available size in order to autogrow // and calculate the scrollbars OwningGrid.RowsPresenterAvailableSize = availableSize; OwningGrid.RowsPresenterEstimatedAvailableHeight = CalculateEstimatedAvailableHeight(availableSize); OwningGrid.OnRowsMeasure(); double totalHeight = -OwningGrid.NegVerticalOffset; double totalCellsWidth = OwningGrid.ColumnsInternal.VisibleEdgedColumnsWidth; double headerWidth = 0; foreach (Control element in OwningGrid.DisplayData.GetScrollingElements()) { DataGridRow row = element as DataGridRow; if (row != null) { if (invalidateRows) { row.InvalidateMeasure(); } } element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); if (row != null && row.HeaderCell != null) { headerWidth = Math.Max(headerWidth, row.HeaderCell.DesiredSize.Width); } else if (element is DataGridRowGroupHeader groupHeader && groupHeader.HeaderCell != null) { headerWidth = Math.Max(headerWidth, groupHeader.HeaderCell.DesiredSize.Width); } totalHeight += element.DesiredSize.Height; } OwningGrid.RowHeadersDesiredWidth = headerWidth; // Could be positive infinity depending on the DataGrid's bounds OwningGrid.AvailableSlotElementRoom = availableSize.Height - totalHeight; totalHeight = Math.Max(0, totalHeight); return(new Size(totalCellsWidth + headerWidth, totalHeight)); }
internal Size ArrangeOverrideImpl(Size finalSize, Vector offset) { if (Child != null) { var padding = Padding; var borderThickness = BorderThickness; var horizontalContentAlignment = HorizontalContentAlignment; var verticalContentAlignment = VerticalContentAlignment; var useLayoutRounding = UseLayoutRounding; var availableSizeMinusMargins = new Size( Math.Max(0, finalSize.Width - padding.Left - padding.Right - borderThickness), Math.Max(0, finalSize.Height - padding.Top - padding.Bottom - borderThickness)); var size = availableSizeMinusMargins; var scale = GetLayoutScale(); var originX = offset.X + padding.Left + borderThickness; var originY = offset.Y + padding.Top + borderThickness; if (horizontalContentAlignment != HorizontalAlignment.Stretch) { size = size.WithWidth(Math.Min(size.Width, DesiredSize.Width - padding.Left - padding.Right)); } if (verticalContentAlignment != VerticalAlignment.Stretch) { size = size.WithHeight(Math.Min(size.Height, DesiredSize.Height - padding.Top - padding.Bottom)); } size = LayoutHelper.ApplyLayoutConstraints(Child, size); if (useLayoutRounding) { size = new Size( Math.Ceiling(size.Width * scale) / scale, Math.Ceiling(size.Height * scale) / scale); availableSizeMinusMargins = new Size( Math.Ceiling(availableSizeMinusMargins.Width * scale) / scale, Math.Ceiling(availableSizeMinusMargins.Height * scale) / scale); } switch (horizontalContentAlignment) { case HorizontalAlignment.Center: case HorizontalAlignment.Stretch: originX += (availableSizeMinusMargins.Width - size.Width) / 2; break; case HorizontalAlignment.Right: originX += availableSizeMinusMargins.Width - size.Width; break; } switch (verticalContentAlignment) { case VerticalAlignment.Center: case VerticalAlignment.Stretch: originY += (availableSizeMinusMargins.Height - size.Height) / 2; break; case VerticalAlignment.Bottom: originY += availableSizeMinusMargins.Height - size.Height; break; } if (useLayoutRounding) { originX = Math.Floor(originX * scale) / scale; originY = Math.Floor(originY * scale) / scale; } Child.Arrange(new Rect(originX, originY, size.Width, size.Height)); } return(finalSize); }