/// <summary> /// Computes the desired size of the <see cref="T:Telerik.Windows.Controls.Primitives.RadUniformGrid"></see> by measuring all of the child elements. /// </summary> /// <returns> /// The desired <see cref="T:System.Windows.Size"></see> based on the child content of the grid and the constraint parameter. /// </returns> /// <param name="availableSize"> /// The <see cref="T:System.Windows.Size"></see> of the available area for the grid. /// </param> protected override Size MeasureOverride(Size availableSize) { this.UpdateComputedValues(); Size calculatedSize = new Size(availableSize.Width / ((double)this.CalculatedColumns), availableSize.Height / ((double)this.CalculatedRows)); if (this.SnapsToDevicePixels) { calculatedSize.Width = Math.Floor(calculatedSize.Width); calculatedSize.Height = Math.Floor(calculatedSize.Height); } double width = 0.0; double height = 0.0; int start = 0; int row = 0; int column = 0; bool horizontal = this.ChildrenFlow == Orientation.Horizontal; if (horizontal) { column = this.CalculatedFirstColumn; } else { row = this.CalculatedFirstColumn; } int count = this.InternalChildren.Count; while (start < count) { UIElement element = InternalChildren[start]; PositionInfo pi = GetPositionInfo(element); if (pi == null) { pi = new PositionInfo(); SetPositionInfo(element, pi); } pi.Column = column; pi.Row = row; if (horizontal) { column++; if (column >= this.columns) { column = 0; row++; } } else { row++; if (row >= this.rows) { row = 0; column++; } } element.Measure(calculatedSize); Size desiredSize = element.DesiredSize; if (width < desiredSize.Width) { width = desiredSize.Width; } if (height < desiredSize.Height) { height = desiredSize.Height; } if (this.SnapsToDevicePixels) { width = Math.Ceiling(width); height = Math.Ceiling(height); } start++; } return(new Size(width * this.CalculatedColumns, height * this.CalculatedRows)); }
private static void SetPositionInfo(DependencyObject obj, PositionInfo value) { obj.SetValue(PositionInfoProperty, value); }
/// <summary> /// Defines the layout of the <see cref="T:Telerik.Windows.Controls.Primitives.RadUniformGrid"></see> by distributing space evenly among all of the child elements. /// </summary> /// <returns> /// The actual <see cref="T:System.Windows.Size"></see> of the grid that is rendered to display the child elements that are visible. /// </returns> /// <param name="finalSize"> /// The <see cref="T:System.Windows.Size"></see> of the area for the grid to use. /// </param> protected override Size ArrangeOverride(Size finalSize) { bool useRounding = this.SnapsToDevicePixels; UIElementCollection collection = this.InternalChildren; // TODO: not implemented in the arange algorithm // bool horizontal = this.ChildrenFlow == Orientation.Horizontal; // TODO: this.CalculatedFirstColumn doesn't have CalculatedFirstRow counterpart! ... should be used here: int firstColumn = this.HideFirstColumn ? 1 : 0; int firstRow = this.HideFirstRow ? 1 : 0; int columnCount = this.CalculatedColumns != 0 ? this.CalculatedColumns : 1; int rowCount = this.CalculatedRows != 0 ? this.CalculatedRows : 1; double width = finalSize.Width / columnCount; double height = finalSize.Height / rowCount; int horizontalExtra = 0; int verticalExtra = 0; Rect currentRect = new Rect(); if (useRounding) { width = Math.Floor(width); height = Math.Floor(height); horizontalExtra = (int)finalSize.Width - ((int)width * columnCount); verticalExtra = (int)finalSize.Height - ((int)height * rowCount); horizontalExtra = CountMissingExtra(horizontalExtra, columnCount); verticalExtra = CountMissingExtra(verticalExtra, rowCount); int[] columnX = new int[columnCount]; int[] columnWidth = new int[columnCount]; int[] rowY = new int[rowCount]; int[] rowHeight = new int[rowCount]; int horizontalSignificientBits = (int)Math.Ceiling(Math.Log(columnCount, 2)); int verticalSignificientBits = (int)Math.Ceiling(Math.Log(rowCount, 2)); int currentColumnX = 0, currentRowY = 0, currentColumnWidth = 0, currentRowHeight = 0; for (var i = 0; i < columnCount; i++) { columnX[i] = currentColumnX; currentColumnWidth = (int)width + (horizontalExtra > FlipInt(i, horizontalSignificientBits) ? 1 : 0); columnWidth[i] = currentColumnWidth; currentColumnX += currentColumnWidth; } for (var i = 0; i < rowCount; i++) { rowY[i] = currentRowY; currentRowHeight = (int)height + (verticalExtra > FlipInt(i, verticalSignificientBits) ? 1 : 0); rowHeight[i] = currentRowHeight; currentRowY += currentRowHeight; } foreach (UIElement element in collection) { PositionInfo pi = GetPositionInfo(element); if (pi.Column < firstColumn || pi.Row < firstRow || pi.Row - firstRow >= rowCount || pi.Column - firstColumn >= columnCount) { // this row or column is hidden so we will move away the child currentRect.Width = 0; currentRect.Height = 0; currentRect.X = double.MinValue; currentRect.Y = double.MinValue; element.Arrange(currentRect); } else if (element.Visibility != Visibility.Collapsed || this.PreserveSpaceForCollapsedChildren) { // this row and column is visible and the child is not collapsed currentRect.Width = columnWidth[pi.Column - firstColumn]; currentRect.Height = rowHeight[pi.Row - firstRow]; currentRect.X = columnX[pi.Column - firstColumn]; currentRect.Y = rowY[pi.Row - firstRow]; element.Arrange(currentRect); } } } else { foreach (UIElement element in collection) { PositionInfo pi = GetPositionInfo(element); currentRect.Width = width; currentRect.Height = height; if (pi.Column < firstColumn || pi.Row < firstRow) { // this row or column is hidden so we will move away the child currentRect.X = double.MinValue; currentRect.Y = double.MinValue; element.Arrange(currentRect); } else if (element.Visibility != Visibility.Collapsed || this.PreserveSpaceForCollapsedChildren) { // this row and column is visible and the child is not collapsed currentRect.X = ((pi.Column - firstColumn) * width) + Math.Min(horizontalExtra, pi.Column - firstColumn); currentRect.Y = ((pi.Row - firstRow) * height) + Math.Min(verticalExtra, pi.Row - firstRow); element.Arrange(currentRect); } } } return(finalSize); }