protected override Size MeasureOverride(Size availableSize)
        {
            int count        = Children.Count;
            var requiredSize = new Size(
                Padding.Left + Padding.Right,
                Padding.Top + Padding.Bottom);

            if (count == 0)
            {
                Cells = null;
                return(requiredSize);
            }

            int    row, col;
            double itemWidth;
            double itemHeight;

            #region cal item size and row col
            var clientSize = new Size(
                availableSize.Width - Padding.Left - Padding.Right,
                availableSize.Height - Padding.Top - Padding.Bottom);

            if (Orientation == Orientation.Horizontal)
            {
                col = MaximumRowsOrColumns;
                row = (int)Math.Ceiling((double)count / col);
            }
            else
            {
                row = MaximumRowsOrColumns;
                col = (int)Math.Ceiling((double)count / row);
            }

            if (double.IsNaN(FixedEdge) || FixedEdge == 0)
            {
                if (Orientation == Orientation.Horizontal)
                {
                    if (double.IsInfinity(clientSize.Width))
                    {
                        itemWidth = GetChildrenMaxSize(clientSize).Width;
                    }
                    else
                    {
                        itemWidth = (clientSize.Width - (col - 1) * HorizontalSpacing) / (3 * col + 1) * 4;
                    }
                    itemHeight = GetHeightFromWidth(itemWidth);
                }
                else
                {
                    if (double.IsInfinity(clientSize.Height))
                    {
                        itemHeight = GetChildrenMaxSize(clientSize).Height;
                    }
                    else
                    {
                        itemHeight = (clientSize.Height - (row - 1) * Spacing - VerticalSpacing) / (row + 0.5);
                    }
                    itemWidth = GetWidthFromHeight(itemHeight);
                }
            }
            else
            {
                itemWidth  = GetWidthFromEdge(FixedEdge);
                itemHeight = GetHeightFromEdge(FixedEdge);

                if (Orientation == Orientation.Horizontal)
                {
                    if (!double.IsInfinity(clientSize.Width))
                    {
                        var needCol = (int)Math.Floor(
                            (clientSize.Width - itemWidth / 4 + HorizontalSpacing)
                            / (3 * itemWidth / 4 + HorizontalSpacing));

                        col = Math.Min(needCol, MaximumRowsOrColumns);
                        row = (int)Math.Ceiling((double)count / col);
                    }
                }
                else
                {
                    if (!double.IsInfinity(clientSize.Height))
                    {
                        var needRow = (int)Math.Floor(
                            (clientSize.Height - itemHeight * 0.5 + Spacing - VerticalSpacing)
                            / (itemHeight + 1));
                        row = Math.Min(needRow, MaximumRowsOrColumns);
                        col = (int)Math.Ceiling((double)count / row);
                    }
                }
            }
            #endregion

            Cells = new SimpleMatrix <Rect>(row, col);
            initCells(itemWidth, itemHeight);

            var itemSize = new Size(itemWidth, itemHeight);
            foreach (var item in Children)
            {
                item.Measure(itemSize);
            }

            var bounds = Cells.GetOutBounds();
            requiredSize.Width  += bounds.Width;
            requiredSize.Height += bounds.Height;
            return(requiredSize);
        }
        protected override Size MeasureOverride(Size availableSize)
        {
            //Debug.WriteLine(requestMeasure + " " + measureId);

            int count        = Children.Count;
            var requiredSize = new Size(
                Padding.Left + Padding.Right,
                Padding.Top + Padding.Bottom);

            if (count == 0 || ColumnCount == 0 || RowCount == 0)
            {
                return(requiredSize);
            }
            try
            {
                measureInProgress = true;
                measureId         = requestMeasure;

                Cells = new SimpleMatrix <Rect>(RowCount, ColumnCount);
                double itemWidth;
                double itemHeight;

                #region cal itemWidth and itemHeight
                if (double.IsNaN(FixedEdge) || FixedEdge == 0)
                {
                    var clientSize = new Size(
                        availableSize.Width - Padding.Left - Padding.Right,
                        availableSize.Height - Padding.Top - Padding.Bottom);

                    if (ColumnCount == 1)
                    {
                        var heightFromClient      = (clientSize.Height - (RowCount - 1) * Spacing) / RowCount;
                        var heightFromClientWidth = GetHeightFromWidth(clientSize.Width);
                        itemHeight = Math.Min(heightFromClient, heightFromClientWidth);
                        itemWidth  = GetWidthFromHeight(itemHeight);
                    }
                    else
                    {
                        if (double.IsInfinity(clientSize.Width) &&
                            double.IsInfinity(clientSize.Height))
                        {
                            var size = GetChildrenMaxSize(clientSize);
                            itemWidth  = size.Width;
                            itemHeight = size.Height;
                        }
                        else if (double.IsInfinity(clientSize.Width))
                        {
                            itemHeight = (clientSize.Height - (RowCount - 1) * Spacing - VerticalSpacing) / (RowCount + 0.5);
                            itemWidth  = GetWidthFromHeight(itemHeight);
                        }
                        else if (double.IsInfinity(clientSize.Height))
                        {
                            itemWidth  = (clientSize.Width - (ColumnCount - 1) * HorizontalSpacing) / (3 * ColumnCount + 1) * 4;
                            itemHeight = GetHeightFromWidth(itemWidth);
                        }
                        else
                        {
                            var bestWidth           = (clientSize.Width - (ColumnCount - 1) * HorizontalSpacing) / (3 * ColumnCount + 1) * 4;
                            var bestHeight          = (clientSize.Height - (RowCount - 1) * Spacing - VerticalSpacing) / (RowCount + 0.5);
                            var widthFromBestHeight = GetWidthFromHeight(bestHeight);
                            itemWidth  = Math.Min(bestWidth, widthFromBestHeight);
                            itemHeight = GetHeightFromWidth(itemWidth);
                        }
                    }
                }
                else
                {
                    itemWidth  = GetWidthFromEdge(FixedEdge);
                    itemHeight = GetHeightFromEdge(FixedEdge);
                }
                #endregion

                initCells(itemWidth, itemHeight);
                var itemSize = new Size(itemWidth, itemHeight);
                foreach (var item in Children)
                {
                    item.Measure(itemSize);
                }

                var bounds = Cells.GetOutBounds();
                requiredSize.Width  += bounds.Width;
                requiredSize.Height += bounds.Height;
                return(requiredSize);
            }
            finally
            {
                measureInProgress = false;
                if (isDirty())
                {
                    InvalidateMeasure();
                }
                else
                {
                    measureId      = 0;
                    requestMeasure = 0;
                }
            }
        }