예제 #1
0
        private void ArrangeChildren()
        {
            var isHorizontal = this.Orientation == Orientation.Horizontal;
            var rowCount     = this.RowDefinitions.Count;
            var columnCount  = this.ColumnDefinitions.Count;

            if (isHorizontal && rowCount == 0 || !isHorizontal && columnCount == 0)
            {
                return;
            }

            var position = 0;

            foreach (UIElement child in Children)
            {
                if (isHorizontal)
                {
                    var row = Math.Min(position % rowCount, rowCount - 1);
                    var col = position / rowCount;

                    Grid.SetRow(child, row);
                    Grid.SetColumn(child, col);
                    position++;
                }
                else
                {
                    var row = position / columnCount;
                    var col = Math.Min(position % columnCount, columnCount - 1);

                    if (row >= rowCount)
                    {
                        RowDefinitions.Add(new RowDefinition()
                        {
                            Height = GridLength.Auto
                        });
                    }

                    Grid.SetRow(child, row);
                    Grid.SetColumn(child, col);
                    position++;
                }
            }

            if (isHorizontal)
            {
                var totalCols = (position / rowCount) + 1;
                if (totalCols < columnCount)
                {
                    ColumnDefinitions.RemoveRange(totalCols - 1, columnCount - totalCols);
                }
            }
            else
            {
                var totalRows = (position / columnCount) + 1;
                if (totalRows < rowCount)
                {
                    RowDefinitions.RemoveRange(totalRows, rowCount - totalRows);
                }
            }
        }
예제 #2
0
        public void ReduceColumns(int newSize)
        {
            List <UIElement> elements = new List <UIElement>();

            foreach (UIElement element in Children)
            {
                if (GetColumn(element) > newSize - 1)
                {
                    elements.Add(element);
                }
            }
            foreach (UIElement element in elements)
            {
                Children.Remove(element);
            }
            ColumnDefinitions.RemoveRange(newSize - 1, ColumnDefinitions.Count - newSize);
        }
예제 #3
0
        /// <summary>
        /// Measures the children of a <see cref="T:System.Windows.Controls.Grid"/> in anticipation of arranging them during the <see cref="FrameworkElement.ArrangeOverride"/> pass.
        /// </summary>
        /// <param name="constraint">Indicates an upper limit size that should not be exceeded.</param>
        /// <returns>
        ///     <see cref="Size"/> that represents the required size to arrange child content.
        /// </returns>
        protected override Size MeasureOverride(Size constraint)
        {
            using (_layoutScope.Enter())
            {
                var isVertical = Orientation == Orientation.Vertical;

                if (_shouldReindex || (IsAutoIndexing &&
                                       ((isVertical && _rowOrColumnCount != ColumnDefinitions.Count) ||
                                        (!isVertical && _rowOrColumnCount != RowDefinitions.Count))))
                {
                    _shouldReindex = false;

                    if (IsAutoIndexing)
                    {
                        _rowOrColumnCount = (isVertical) ? ColumnDefinitions.Count : RowDefinitions.Count;
                        if (_rowOrColumnCount == 0)
                        {
                            _rowOrColumnCount = 1;
                        }

                        var cellCount         = 0;
                        var currentRow        = 0;
                        var currentColumn     = 0;
                        var reservedPositions = new HashSet <ReservedPosition>();

                        foreach (UIElement child in Children)
                        {
                            ChildLayoutInfo layoutInfo;

                            if (!_childData.TryGetValue(child, out layoutInfo))
                            {
                                layoutInfo = new ChildLayoutInfo
                                {
                                    OriginalColumn = Undefined,
                                    OriginalRow    = Undefined
                                };

                                if (!child.HasDefaultValue(ColumnProperty))
                                {
                                    layoutInfo.OriginalColumn = GetColumn(child);

                                    if ((Orientation == Orientation.Vertical) &&
                                        (layoutInfo.OriginalColumn >= ColumnDefinitions.Count))
                                    {
                                        layoutInfo.OriginalColumn = ColumnDefinitions.Count - 1;
                                    }
                                }

                                if (!child.HasDefaultValue(RowProperty))
                                {
                                    layoutInfo.OriginalRow = GetRow(child);

                                    if ((Orientation == Orientation.Horizontal) &&
                                        (layoutInfo.OriginalRow >= RowDefinitions.Count))
                                    {
                                        layoutInfo.OriginalRow = RowDefinitions.Count - 1;
                                    }
                                }

                                _childData[child] = layoutInfo;
                            }

                            if (layoutInfo.OriginalColumn != Undefined)
                            {
                                if (layoutInfo.OriginalRow != Undefined)
                                {
                                    layoutInfo.ActualColumn = layoutInfo.OriginalColumn;
                                    layoutInfo.ActualRow    = layoutInfo.OriginalRow;
                                    reservedPositions.Add(
                                        new ReservedPosition(
                                            layoutInfo.ActualColumn,
                                            layoutInfo.ActualRow));
                                }
                                else if (isVertical)
                                {
                                    while ((layoutInfo.OriginalColumn != currentColumn) ||
                                           reservedPositions.Contains(new ReservedPosition(currentRow, currentColumn)))
                                    {
                                        ++cellCount;
                                        if (++currentColumn >= _rowOrColumnCount)
                                        {
                                            currentColumn = 0;
                                            ++currentRow;
                                        }
                                    }
                                    layoutInfo.ActualRow    = currentRow;
                                    layoutInfo.ActualColumn = currentColumn;
                                }
                            }
                            else if (layoutInfo.OriginalRow != Undefined)
                            {
                                if (!isVertical)
                                {
                                    while ((layoutInfo.OriginalRow != currentRow) ||
                                           reservedPositions.Contains(new ReservedPosition(currentRow, currentColumn)))
                                    {
                                        ++cellCount;
                                        if (++currentRow >= _rowOrColumnCount)
                                        {
                                            currentRow = 0;
                                            ++currentColumn;
                                        }
                                    }
                                    layoutInfo.ActualRow    = currentRow;
                                    layoutInfo.ActualColumn = currentColumn;
                                }
                            }
                            else
                            {
                                while (reservedPositions.Contains(new ReservedPosition(currentRow, currentColumn)))
                                {
                                    ++cellCount;
                                    if (isVertical)
                                    {
                                        if (++currentColumn >= _rowOrColumnCount)
                                        {
                                            currentColumn = 0;
                                            ++currentRow;
                                        }
                                    }
                                    else
                                    {
                                        if (++currentRow >= _rowOrColumnCount)
                                        {
                                            currentRow = 0;
                                            ++currentColumn;
                                        }
                                    }
                                }
                                layoutInfo.ActualColumn = currentColumn;
                                layoutInfo.ActualRow    = currentRow;
                            }

                            ++cellCount;

                            SetRow(child, layoutInfo.ActualRow);
                            SetColumn(child, layoutInfo.ActualColumn);

                            var childRowSpan    = GetRowSpan(child);
                            var childColumnSpan = GetColumnSpan(child);

                            if (isVertical)
                            {
                                if (!child.HasDefaultValue(ColumnSpanProperty))
                                {
                                    if ((currentColumn + childColumnSpan) >= _rowOrColumnCount)
                                    {
                                        childColumnSpan -= ((currentColumn + childColumnSpan) - _rowOrColumnCount - 1);
                                    }

                                    cellCount += childRowSpan * childColumnSpan;

                                    for (var i = 0; i < (childColumnSpan - 1); i++)
                                    {
                                        reservedPositions.Add(new ReservedPosition(currentRow, currentColumn + i));
                                    }
                                }
                                if (!child.HasDefaultValue(RowSpanProperty))
                                {
                                    cellCount += childRowSpan * childColumnSpan;

                                    for (var i = 0; i < (childRowSpan - 1); i++)
                                    {
                                        reservedPositions.Add(new ReservedPosition(currentRow + i, currentColumn));
                                    }
                                }
                                else if (++currentColumn >= _rowOrColumnCount)
                                {
                                    currentColumn = 0;
                                    ++currentRow;
                                }
                            }
                            else
                            {
                                if (!child.HasDefaultValue(RowSpanProperty))
                                {
                                    if ((currentColumn + childRowSpan) >= _rowOrColumnCount)
                                    {
                                        childRowSpan -= ((currentColumn + childRowSpan) - _rowOrColumnCount - 1);
                                    }

                                    cellCount += childRowSpan * childColumnSpan;

                                    for (var i = 0; i < (childRowSpan - 1); i++)
                                    {
                                        reservedPositions.Add(new ReservedPosition(currentRow + i, currentColumn));
                                    }
                                }
                                if (!child.HasDefaultValue(ColumnSpanProperty))
                                {
                                    cellCount += childRowSpan * childColumnSpan;

                                    for (var i = 0; i < (childColumnSpan - 1); i++)
                                    {
                                        reservedPositions.Add(new ReservedPosition(currentRow, currentColumn + i));
                                    }
                                }
                                else if (++currentRow >= _rowOrColumnCount)
                                {
                                    currentRow = 0;
                                    ++currentColumn;
                                }
                            }
                        }

                        //  Update the number of rows/columns
                        if (isVertical)
                        {
                            int newRowCount = ((cellCount - 1) / _rowOrColumnCount + 1);
                            while (RowDefinitions.Count < newRowCount)
                            {
                                RowDefinitions.Add(new RowDefinition {
                                    Height = GridLength.Auto
                                });
                            }
                            if (RowDefinitions.Count > newRowCount)
                            {
                                RowDefinitions.RemoveRange(newRowCount, RowDefinitions.Count - newRowCount);
                            }
                        }
                        else // horizontal
                        {
                            int newColumnCount = ((cellCount - 1) / _rowOrColumnCount + 1);
                            while (ColumnDefinitions.Count < newColumnCount)
                            {
                                ColumnDefinitions.Add(new ColumnDefinition {
                                    Width = GridLength.Auto
                                });
                            }
                            if (ColumnDefinitions.Count > newColumnCount)
                            {
                                ColumnDefinitions.RemoveRange(newColumnCount, ColumnDefinitions.Count - newColumnCount);
                            }
                        }
                    }

                    // Set margin and alignment
                    foreach (UIElement child in Children)
                    {
                        if (ChildMargin != null)
                        {
                            child.SetIfDefault(MarginProperty, ChildMargin.Value);
                        }
                        if (ChildHorizontalAlignment != null)
                        {
                            child.SetIfDefault(HorizontalAlignmentProperty, ChildHorizontalAlignment.Value);
                        }
                        if (ChildVerticalAlignment != null)
                        {
                            child.SetIfDefault(VerticalAlignmentProperty, ChildVerticalAlignment.Value);
                        }
                    }
                }

                return(base.MeasureOverride(constraint));
            }
        }
예제 #4
0
        public void PerformLayout()
        {
            bool isVertical = Orientation == Orientation.Vertical;

            if (_shouldReindex || (IsAutoIndexing &&
                                   ((isVertical && _rowOrColumnCount != ColumnDefinitions.Count) ||
                                    (!isVertical && _rowOrColumnCount != RowDefinitions.Count))))
            {
                _shouldReindex = false;

                if (IsAutoIndexing)
                {
                    _rowOrColumnCount = (ColumnDefinitions.Count != 0) ? ColumnDefinitions.Count : RowDefinitions.Count;
                    if (_rowOrColumnCount == 0)
                    {
                        _rowOrColumnCount = 1;
                    }

                    int cellCount = 0;
                    foreach (UIElement child in Children)
                    {
                        if (GetAutoIndex(child) == false)
                        {
                            continue;
                        }
                        cellCount += (ColumnDefinitions.Count != 0) ? Grid.GetColumnSpan(child) : Grid.GetRowSpan(child);
                    }

                    //  Update the number of rows/columns
                    if (ColumnDefinitions.Count != 0)
                    {
                        var newRowCount = (int)Math.Ceiling((double)cellCount / (double)_rowOrColumnCount);
                        while (RowDefinitions.Count < newRowCount)
                        {
                            var rowDefinition = new RowDefinition();
                            rowDefinition.Height = RowHeight;
                            RowDefinitions.Add(rowDefinition);
                        }
                        if (RowDefinitions.Count > newRowCount)
                        {
                            RowDefinitions.RemoveRange(newRowCount, RowDefinitions.Count - newRowCount);
                        }
                    }
                    else // rows defined
                    {
                        var newColumnCount = (int)Math.Ceiling((double)cellCount / (double)_rowOrColumnCount);
                        while (ColumnDefinitions.Count < newColumnCount)
                        {
                            var columnDefinition = new ColumnDefinition();
                            columnDefinition.Width = ColumnWidth;
                            ColumnDefinitions.Add(columnDefinition);
                        }
                        if (ColumnDefinitions.Count > newColumnCount)
                        {
                            ColumnDefinitions.RemoveRange(newColumnCount, ColumnDefinitions.Count - newColumnCount);
                        }
                    }
                }

                //  Update children indices
                int cellPosition = 0;
                var cellsToSkip  = new Queue <int>();
                foreach (UIElement child in Children)
                {
                    if (IsAutoIndexing && GetAutoIndex(child) == true)
                    {
                        if (cellsToSkip.Any() && cellsToSkip.Peek() == cellPosition)
                        {
                            cellsToSkip.Dequeue();
                            cellPosition += 1;
                        }

                        if (!isVertical) // horizontal (default)
                        {
                            var rowIndex = cellPosition / ColumnDefinitions.Count;
                            Grid.SetRow(child, rowIndex);

                            var columnIndex = cellPosition % ColumnDefinitions.Count;
                            Grid.SetColumn(child, columnIndex);

                            var rowSpan = Grid.GetRowSpan(child);
                            if (rowSpan > 1)
                            {
                                Enumerable.Range(1, rowSpan).ToList()
                                .ForEach(x => cellsToSkip.Enqueue(cellPosition + ColumnDefinitions.Count * x));
                            }

                            var overrideRowHeight = AutoGrid.GetRowHeightOverride(child);
                            if (overrideRowHeight != null)
                            {
                                RowDefinitions[rowIndex].Height = overrideRowHeight.Value;
                            }

                            var overrideColumnWidth = AutoGrid.GetColumnWidthOverride(child);
                            if (overrideColumnWidth != null)
                            {
                                ColumnDefinitions[columnIndex].Width = overrideColumnWidth.Value;
                            }

                            cellPosition += Grid.GetColumnSpan(child);
                        }
                        else
                        {
                            var rowIndex = cellPosition % RowDefinitions.Count;
                            Grid.SetRow(child, rowIndex);

                            var columnIndex = cellPosition / RowDefinitions.Count;
                            Grid.SetColumn(child, columnIndex);

                            var columnSpan = Grid.GetColumnSpan(child);
                            if (columnSpan > 1)
                            {
                                Enumerable.Range(1, columnSpan).ToList()
                                .ForEach(x => cellsToSkip.Enqueue(cellPosition + RowDefinitions.Count * x));
                            }

                            var overrideRowHeight = AutoGrid.GetRowHeightOverride(child);
                            if (overrideRowHeight != null)
                            {
                                RowDefinitions[rowIndex].Height = overrideRowHeight.Value;
                            }

                            var overrideColumnWidth = AutoGrid.GetColumnWidthOverride(child);
                            if (overrideColumnWidth != null)
                            {
                                ColumnDefinitions[columnIndex].Width = overrideColumnWidth.Value;
                            }

                            cellPosition += Grid.GetRowSpan(child);
                        }
                    }

                    // Set margin and alignment
                    if (ChildMargin != null)
                    {
                        DependencyHelpers.SetIfDefault(child, FrameworkElement.MarginProperty, ChildMargin.Value);
                    }
                    if (ChildHorizontalAlignment != null)
                    {
                        DependencyHelpers.SetIfDefault(child, FrameworkElement.HorizontalAlignmentProperty, ChildHorizontalAlignment.Value);
                    }
                    if (ChildVerticalAlignment != null)
                    {
                        DependencyHelpers.SetIfDefault(child, FrameworkElement.VerticalAlignmentProperty, ChildVerticalAlignment.Value);
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        ///     Measures the children of a <see cref="T:System.Windows.Controls.Grid" /> in anticipation of arranging them during
        ///     the <see cref="M:ArrangeOverride" /> pass.
        /// </summary>
        /// <param name="constraint">Indicates an upper limit size that should not be exceeded.</param>
        /// <returns>
        ///     <see cref="Size" /> that represents the required size to arrange child content.
        /// </returns>
        protected override Size MeasureOverride(Size constraint)
        {
            bool isVertical = Orientation == Orientation.Vertical;

            if (_shouldReindex || (IsAutoIndexing &&
                                   ((isVertical && _rowOrColumnCount != ColumnDefinitions.Count) ||
                                    (!isVertical && _rowOrColumnCount != RowDefinitions.Count))))
            {
                _shouldReindex = false;

                if (IsAutoIndexing)
                {
                    _rowOrColumnCount = (isVertical) ? ColumnDefinitions.Count : RowDefinitions.Count;
                    if (_rowOrColumnCount == 0)
                    {
                        _rowOrColumnCount = 1;
                    }

                    int cellCount = InternalChildren.Cast <UIElement>().Sum(child =>
                                                                            (isVertical) ? GetColumnSpan(child) : GetRowSpan(child));

                    //  Update the number of rows/columns
                    if (isVertical)
                    {
                        int newRowCount = ((cellCount - 1) / _rowOrColumnCount + 1);
                        while (RowDefinitions.Count < newRowCount)
                        {
                            RowDefinitions.Add(new RowDefinition());
                        }
                        if (RowDefinitions.Count > newRowCount)
                        {
                            RowDefinitions.RemoveRange(newRowCount, RowDefinitions.Count - newRowCount);
                        }
                    }
                    else // horizontal
                    {
                        int newColumnCount = ((cellCount - 1) / _rowOrColumnCount + 1);
                        while (ColumnDefinitions.Count < newColumnCount)
                        {
                            ColumnDefinitions.Add(new ColumnDefinition());
                        }
                        if (ColumnDefinitions.Count > newColumnCount)
                        {
                            ColumnDefinitions.RemoveRange(newColumnCount, ColumnDefinitions.Count - newColumnCount);
                        }
                    }
                }

                //  Update children indices
                int position = 0;
                foreach (UIElement child in Children)
                {
                    if (IsAutoIndexing)
                    {
                        if (isVertical)
                        {
                            SetRow(child, position / _rowOrColumnCount);
                            SetColumn(child, position % _rowOrColumnCount);
                            position += GetColumnSpan(child);
                        }
                        else
                        {
                            SetRow(child, position % _rowOrColumnCount);
                            SetColumn(child, position / _rowOrColumnCount);
                            position += GetRowSpan(child);
                        }
                    }

                    // Set margin and alignment
                    if (ChildMargin != null)
                    {
                        child.SetIfDefault(MarginProperty, ChildMargin.Value);
                    }
                    if (ChildHorizontalAlignment != null)
                    {
                        child.SetIfDefault(HorizontalAlignmentProperty, ChildHorizontalAlignment.Value);
                    }
                    if (ChildVerticalAlignment != null)
                    {
                        child.SetIfDefault(VerticalAlignmentProperty, ChildVerticalAlignment.Value);
                    }
                }
            }

            return(base.MeasureOverride(constraint));
        }