Как расположить элементы управления так, чтобы они занимали минимум места:
(вверху: исходный макет, внизу: итоговый макет)
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/.
Наоборот: (оригинальный ответ)
Вы можете каким-то образом реорганизовать элементы управления, используя этот метод:
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++);
}
}
}
}
Исходный макет:
Новый макет:
Примечание: они упорядочены в порядке их обнаружения, т. е. если вы не хотите. 3 после нет. 4 вам придется вручную поместить его после нет. 4 перед реорганизацией панели.
person
aybe
schedule
15.10.2014
FlowBreak
свойств элементов внутри Panel значение False? - person aybe   schedule 15.10.2014