我使用FlowLayoutPanel控件,我想知道是否还要执行控件的自动布局,以便它们占用尽可能低的空间? 例如,添加1个宽度为100px的控件,3个宽度为500px的控件和1个100px的控件。
它应该是这样的:
##Control1##
##############Control2##########################
##############Control3##########################
##############Control4##########################
##Control5##
正如你所看到的,有些空间正在被浪费,无论如何都要优化它的位置以达到这样的效果而无需手动重新定位?
##Control1## ##Control5##
##############Control2##########################
##############Control3##########################
##############Control4##########################
答案 0 :(得分:2)
(顶部:初始布局,底部:结果布局)
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++);
}
}
}
现在,您在使用时可能会遇到用户体验&#39; 问题,就像您希望其中某些问题符合特定顺序一样。解决此类问题的方法是将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/。
您可以使用此方法以某种方式重新组织控件:
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你必须在没有之后手动放置它。 4在重组小组之前。