Microsoft.Phone.Controls.WrapPanel.ArrangeOverride C# (CSharp) Method

ArrangeOverride() protected method

protected ArrangeOverride ( Size finalSize ) : Size
finalSize Windows.Foundation.Size
return Windows.Foundation.Size
        protected override Size ArrangeOverride( Size finalSize )
        {
            // Variables tracking the size of the current line, and the maximum
            // size available to fill.  Note that the line might represent a row
            // or a column depending on the orientation.
            Orientation o = Orientation;
            OrientedSize lineSize = new OrientedSize( o );
            OrientedSize maximumSize = new OrientedSize( o, finalSize.Width, finalSize.Height );

            // Determine the constraints for individual items
            double itemWidth = ItemWidth;
            double itemHeight = ItemHeight;
            bool hasFixedWidth = !itemWidth.IsNaN();
            bool hasFixedHeight = !itemHeight.IsNaN();
            double indirectOffset = 0;
            double? directDelta = ( o == Orientation.Horizontal ) ?
                ( hasFixedWidth ? ( double? ) itemWidth : null ) :
                ( hasFixedHeight ? ( double? ) itemHeight : null );

            // Measure each of the Children.  We will process the elements one
            // line at a time, just like during measure, but we will wait until
            // we've completed an entire line of elements before arranging them.
            // The lineStart and lineEnd variables track the size of the
            // currently arranged line.
            UIElementCollection children = Children;
            int count = children.Count;
            int lineStart = 0;
            for ( int lineEnd = 0; lineEnd < count; lineEnd++ )
            {
                UIElement element = children[ lineEnd ];

                // Get the size of the element
                OrientedSize elementSize = new OrientedSize(
                    o,
                    hasFixedWidth ? itemWidth : element.DesiredSize.Width,
                    hasFixedHeight ? itemHeight : element.DesiredSize.Height );

                // If this element falls of the edge of the line
                if ( NumericExtensions.IsGreaterThan( lineSize.Direct + elementSize.Direct, maximumSize.Direct ) )
                {
                    // Then we just completed a line and we should arrange it
                    ArrangeLine( lineStart, lineEnd, directDelta, indirectOffset, lineSize.Indirect );

                    // Move the current element to a new line
                    indirectOffset += lineSize.Indirect;
                    lineSize = elementSize;

                    // If the current element is larger than the maximum size
                    if ( NumericExtensions.IsGreaterThan( elementSize.Direct, maximumSize.Direct ) )
                    {
                        // Arrange the element as a single line
                        ArrangeLine( lineEnd, ++lineEnd, directDelta, indirectOffset, elementSize.Indirect );

                        // Move to a new line
                        indirectOffset += lineSize.Indirect;
                        lineSize = new OrientedSize( o );
                    }

                    // Advance the start index to a new line after arranging
                    lineStart = lineEnd;
                }
                else
                {
                    // Otherwise just add the element to the end of the line
                    lineSize.Direct += elementSize.Direct;
                    lineSize.Indirect = Math.Max( lineSize.Indirect, elementSize.Indirect );
                }
            }

            // Arrange any elements on the last line
            if ( lineStart < count )
            {
                ArrangeLine( lineStart, count, directDelta, indirectOffset, lineSize.Indirect );
            }

            return finalSize;
        }