/// <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);
        }