コード例 #1
0
        /// <summary>
        /// 添加或移除一个元素布局
        /// </summary>
        private void LayoutItem(UIElement item)
        {
            //开始布局
            StackLayoutContext minStack = layoutContext.First(c => c.Lenght == layoutContext.Min(s => s.Lenght));

            if (Orientation == Orientation.Vertical)
            {
                Size  availableSize = new Size(minStack.Width, double.PositiveInfinity);
                Point coordinate    = new Point(minStack.Offset, minStack.Lenght);
                item.Measure(availableSize);
                SetArrange(item, new Rect(coordinate, item.DesiredSize));
                minStack.Lenght += item.DesiredSize.Height + ItemsSpacing;
            }
            else
            {
                Size  availableSize = new Size(double.PositiveInfinity, minStack.Width);
                Point coordinate    = new Point(minStack.Lenght, minStack.Offset);
                item.Measure(availableSize);
                SetArrange(item, new Rect(coordinate, item.DesiredSize));
                minStack.Lenght += item.DesiredSize.Width + ItemsSpacing;
            }

            if (item is IVirtualizingItem)
            {
                if (ShouldBeVirtualized(item))
                {
                    (item as IVirtualizingItem).Virtualize();
                }
                else
                {
                    if (minStack.FirstRealizedItemIndex == -1)
                    {
                        minStack.FirstRealizedItemIndex = minStack.Elements.Count;
                    }
                    minStack.RealizedItemCount++;
                    (item as IVirtualizingItem).Realize();
                }
            }
            minStack.Elements.Add(item);
            //完成一个子项布局,布局请求递减
            layoutRequest--;
        }
コード例 #2
0
        /// <summary>
        /// 布局初始化,初始化所有子项的布局
        /// </summary>
        private void LayoutInitialize(Size availableSize)
        {
            //清除布局上下文数据
            layoutContext.Clear();

            double availableWidth  = availableSize.Width - Padding.Left - Padding.Right;
            double availableHeight = availableSize.Height - Padding.Top - Padding.Bottom;

            //计算子项固定边大小
            _columnWidth = Math.Min(DesiredColumnWidth, availableWidth);
            int    numColumns = Math.Max(1, (int)Math.Floor(availableWidth / _columnWidth));
            double totalWidth = _columnWidth + ((numColumns - 1) * (_columnWidth + ColumnSpacing));

            if (totalWidth > availableWidth)
            {
                numColumns--;
            }
            else if (double.IsInfinity(availableWidth))
            {
                availableWidth = totalWidth;
            }
            if (HorizontalAlignment == HorizontalAlignment.Stretch)
            {
                availableWidth = availableWidth - ((numColumns - 1) * ColumnSpacing);
                _columnWidth   = availableWidth / numColumns;
            }
            double offset = ((Orientation == Orientation.Vertical ? availableWidth : availableHeight) - (numColumns * ColumnSpacing)) / numColumns;

            //为每个栈生成布局上下文数据
            for (int i = 0; i < numColumns; i++)
            {
                layoutContext.Add(new StackLayoutContext()
                {
                    //每个栈的子项的固定偏移,纵向排版就为 X 坐标,横向就为 Y 坐标
                    Offset = (offset + ColumnSpacing) * i,
                    Width  = offset
                });
            }

            //遍历子项为每个子项进行测量
            foreach (var item in this.Children)
            {
                //寻找长度最短的栈
                StackLayoutContext minStack = layoutContext.First(c => c.Lenght == layoutContext.Min(s => s.Lenght));

                //根据不同的布局方向进行布局
                if (Orientation == Orientation.Vertical)
                {
                    //栈的固定长度,纵向排版为宽,横向为高
                    availableSize.Width = offset;
                    //子项的坐标,栈的目前长度与栈的固定偏移
                    Point coordinate = new Point(minStack.Offset, minStack.Lenght);
                    //测量子项所需尺寸
                    item.Measure(availableSize);
                    //将测量结果保存在附加属性 Arrange 中,以便布局时使用
                    SetArrange(item, new Rect(coordinate, item.DesiredSize));
                    //将最短栈加上当前子项的长度与子项间距
                    minStack.Lenght += item.DesiredSize.Height + ItemsSpacing;
                }
                else
                {
                    availableSize.Height = offset;
                    Point coordinate = new Point(minStack.Lenght, minStack.Offset);
                    item.Measure(availableSize);
                    SetArrange(item, new Rect(coordinate, item.DesiredSize));
                    minStack.Lenght += item.DesiredSize.Width + ItemsSpacing;
                }

                //判断子项是否实现 IVirtualizingItem 接口
                if (item is IVirtualizingItem)
                {
                    //判断子项是否应该被虚拟化
                    if (ShouldBeVirtualized(item))
                    {
                        (item as IVirtualizingItem).Virtualize();
                    }
                    else
                    {
                        if (minStack.FirstRealizedItemIndex == -1)
                        {
                            minStack.FirstRealizedItemIndex = minStack.Elements.Count;
                        }
                        minStack.RealizedItemCount++;
                        (item as IVirtualizingItem).Realize();
                    }
                }
                //添加子项到最短栈的结尾
                minStack.Elements.Add(item);
            }

            layoutRequest = 0;
        }