首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >安排FlowLayoutPanel控件以占用最少的空间

安排FlowLayoutPanel控件以占用最少的空间
EN

Stack Overflow用户
提问于 2014-10-14 19:54:17
回答 1查看 777关注 0票数 1

我使用FlowLayoutPanel控件,我想知道是否有任何方法来执行控件的自动布局,以便它们占用尽可能低的空间?例如,添加一个宽度为100 and的控件,三个宽度为500 and的控件,再添加一个宽度为100 and的控件。

它应该是这样的:

代码语言:javascript
运行
复制
##Control1##
##############Control2##########################
##############Control3##########################
##############Control4##########################
##Control5##

正如你所看到的,一些空间正在被浪费,是否有优化它的位置来实现这样的东西而不手动重新定位?

代码语言:javascript
运行
复制
##Control1## ##Control5##
##############Control2##########################
##############Control3##########################
##############Control4##########################
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-15 18:40:15

如何安排控件以占用最少的空间:

(顶部:初始布局,底部:结果布局)

代码语言:javascript
运行
复制
public partial class Form1 : Form
{
    public Form1() {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {
        var flowLayoutPanel = flowLayoutPanel1;
        ReorganizeFlowLayoutPanel(flowLayoutPanel);
    }

    private static void ReorganizeFlowLayoutPanel(FlowLayoutPanel flowLayoutPanel) {
        var width = flowLayoutPanel.Width;
        var controls = flowLayoutPanel.Controls.OfType<Control>().ToList();
        var ascending = new List<Control>(controls.OrderBy(s => s.Width));
        var descending = new List<Control>(controls.OrderByDescending(s => s.Width));

        var list = new List<Control>();
        while (ascending.Count > 0) {
            Control smallest = ascending[0];
            ascending.RemoveAt(0);
            if (ascending.Count == 0) {
                list.Add(smallest);
                break;
            }
            foreach (var largest in descending) {
                if (smallest.Width + largest.Width < width) {
                    list.Add(smallest);
                    list.Add(largest);
                    ascending.Remove(largest);
                    descending.Remove(largest);
                    descending.Remove(smallest);
                    break;
                }
            }
        }
        var i = 0;
        foreach (var control in list) {
            flowLayoutPanel.Controls.SetChildIndex(control, i++);
        }
    }
}

现在,您可能会在使用它时遇到“用户体验”问题,就像您期望它们中的一些处于特定的顺序一样。要解决这样的问题,您可以做的是将Control.Tag属性设置为某些字符串,如"Priority=1""Priority=2"等.

然后将ascending的定义替换为:

var ascending = new List<Control>(controls.OrderBy(s => s.Width).ThenBy(s=>(string)s.Tag) );

没有优先级标签的排列:

带有优先级标签的排列:

我已经演示过的示例非常简单,您可能希望使用自己的逻辑来更好地区分您的控件。

注:--这是一种非常天真的方法,如果您正在寻找一种更复杂的算法,那么您应该从雪碧片纹理制造商(如http://spritesheetpacker.codeplex.com/ )那里获得一些灵感。

相反:(原来的答案)

您可以使用此方法以某种方式重新组织控件:

代码语言:javascript
运行
复制
using System;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1() {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) {
            var flowLayoutPanel = flowLayoutPanel1;
            ReorganizeFlowLayoutPanel(flowLayoutPanel);
        }

        private static void ReorganizeFlowLayoutPanel(FlowLayoutPanel flowLayoutPanel) {
            var controls = flowLayoutPanel.Controls.OfType<Control>().OrderBy(s => s.Width);
            var index = 0;
            foreach (var tuple in controls) {
                flowLayoutPanel.Controls.SetChildIndex(tuple, index++);
            }
        }
    }
}

初始布局:

新布局:

注意:它们是按发现的顺序排序的,也就是说,如果您想在4号之后选择3号,那么在重新组织面板之前,您必须手动将其放在4号之后。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26369210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档