【问题标题】:Wrap panel with "kind of" two way wraping用“一种”两种方式包裹面板
【发布时间】:2011-10-02 09:28:17
【问题描述】:

所以我有一个垂直包裹的包裹面板。这些项目是在运行时添加的,但所有这些项目(用户控件)都有不同的宽度,并且因为包装面板是垂直包装的,所以它会将它们堆叠在下方,当它们覆盖垂直空间时,它们会包装到下一列。但是我需要的是“一种”双向包装,即我添加了第一个宽度为 200px 的项目,然后我添加了第二个宽度为 50px 的项目,但是当我添加第三个项目时,它的宽度为 100px宽度我希望它不要转到下一行,而是将其自身放置在那个空闲的位置,根据顶部的 200 像素控件(留下 150 像素的空间和 100 像素的控件显然适合)。当然放不下的时候会换到下一行,这样就OK了。

这里有一张图片来说明这一点(这里不能上传):

这就是发生的事情: image 1

这就是我想要的: image 2


对不起,我的英语不是我的主要语言。希望你能理解我的问题。

【问题讨论】:

    标签: wpf word-wrap wrappanel


    【解决方案1】:

    您绝对不能使用单个面板来完成此操作!您可以使用堆栈面板插入多个水平方向的动态包装面板,以获得您需要的“列”行为

    【讨论】:

    • 这就是我必须使用单个面板来做到这一点的问题:\ 我可以制作像 Wrappanel-in-a-wrappanel 这样的东西,但这对我不起作用......我在想关于自定义包装板,但这就是我要问的;如何编写一个适用于我所描述行为的代码:?
    【解决方案2】:

    好吧,我做到了。刚刚用我想要的行为编写了一个自定义包装面板。

    这里是:

    public class TwoWayWrapPanel : Panel
    {
    int _rowCount = 0;
    
    public int RowCount
    {
        get { return _rowCount; }
        set { _rowCount = value; }
    }
    
    protected override Size MeasureOverride(Size availableSize)
    {
        Size resultSize = new Size(0, 0);
        double columnWidth = 0;
        double usedSpace = 0;
        double nullX = 0;
        double currentX = 0;
        double currentY = 0;
        bool isFirst = true;
        int row = 0;
    
        foreach (UIElement child in Children)
        {
            child.Measure(availableSize);
    
            if (isFirst)
            {
                columnWidth = child.DesiredSize.Width;
                resultSize.Width += columnWidth;
                currentY += child.DesiredSize.Height;
                row++;
                isFirst = false;
            }
            else
            {
                if (columnWidth >= usedSpace + child.DesiredSize.Width & _rowCount > 1)
                {
                    currentX = nullX + usedSpace;
                    usedSpace += child.DesiredSize.Width;
                }
                else
                {
                    row++;
    
                    if (row + 1 > _rowCount | child.DesiredSize.Width > columnWidth)
                    {
                        row = 0;
                        currentX = nullX + columnWidth;
                        nullX = currentX;
                        usedSpace = 0;
                        columnWidth = child.DesiredSize.Width;
                        currentY = child.DesiredSize.Height;
                        row++;
                        resultSize.Width += columnWidth;
                    }
                    else
                    {
                        currentY += child.DesiredSize.Height;
                        currentX = nullX;
                        usedSpace = child.DesiredSize.Width;
                    }
                }
            }
        }
    
        return resultSize;
    }
    
    protected override Size ArrangeOverride(Size finalSize)
    {
        double columnWidth = 0;
        double usedSpace = 0;
        double nullX = 0;
        double currentX = 0;
        double currentY = 0;
        bool isFirst = true;
        int row = 0;
    
        foreach (UIElement child in Children)
        {
            //First item in the collection
            if (isFirst)
            { 
                child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
                columnWidth = child.DesiredSize.Width;
                currentY += child.DesiredSize.Height;
                row++;
                isFirst = false;
            }
            else
            {
                //Current item fits so place it in the same row
                if (columnWidth >= usedSpace + child.DesiredSize.Width & _rowCount > 1)
                {
                    currentX = nullX + usedSpace;
                    child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
                    usedSpace += child.DesiredSize.Width;
                }
                else
                {
                    row++;
    
                    //The row limit is reached or the item width is greater than primary item width. Creating new column
                    if (row + 1 > _rowCount | child.DesiredSize.Width > columnWidth)
                    {
                        row = 0;
                        currentY = 0;
                        currentX = nullX + columnWidth;
                        nullX = currentX;
                        usedSpace = 0;
                        child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
                        columnWidth = child.DesiredSize.Width;
                        currentY += child.DesiredSize.Height;
                        row++;
                    }
                    //Item doesn't fit. Adding to the new row in the same column
                    else
                    {
                        usedSpace = 0;
                        currentY += child.DesiredSize.Height;
                        currentX = nullX;
                        child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
                        usedSpace += child.DesiredSize.Width;
                    }
                }
            }
        }
    
        return finalSize;
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-27
      • 2017-02-06
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 2015-08-09
      • 2014-05-03
      • 2014-10-14
      相关资源
      最近更新 更多