該代碼段執行此操作:
它安排在相對於縱橫比的一個容器內的可見的控件(參見編碼R變量),並使用該容器邊距值來獲得項目之間的水平和垂直間隙。容器的填充也被處理。
public static void Arrange(Control container)
{
var H = container.DisplayRectangle.Height;
var W = container.DisplayRectangle.Width;
var N = container.Controls.OfType<Control>().Count(c => c.Visible);
var R = 4/3d; // item aspect ratio
var margin = container.Margin;
var padding = container.Padding;
var horizontalGap = margin.Left + margin.Right;
var verticalGap = margin.Top + margin.Bottom;
if (N == 0)
return;
var bestSizedItem = (
// Try n rows
Enumerable.Range(1, N).Select(testRowCount =>
{
var testItemHeight = (H - verticalGap * (testRowCount - 1))/testRowCount;
return new
{
testColCount = (int)Math.Ceiling((double)N/testRowCount),
testRowCount = testRowCount,
testItemHeight = (int)testItemHeight,
testItemWidth = (int)(testItemHeight * R)
};
})
// Try n columns
.Concat(
Enumerable.Range(1, N).Select(testColCount =>
{
var testItemWidth = (W - horizontalGap * (testColCount - 1))/testColCount;
return new
{
testColCount = testColCount,
testRowCount = (int)Math.Ceiling((double)N/testColCount),
testItemHeight = (int)(testItemWidth/R),
testItemWidth = (int)testItemWidth
};
})))
// Remove when it's too big
.Where(item => item.testItemWidth * item.testColCount + horizontalGap * (item.testColCount - 1) <= W &&
item.testItemHeight * item.testRowCount + verticalGap * (item.testRowCount - 1) <= H)
// Get the biggest area
.OrderBy(item => item.testItemHeight * item.testItemWidth)
.LastOrDefault();
Debug.Assert(bestSizedItem != null);
if (bestSizedItem == null)
return;
int x = container.DisplayRectangle.X;
int y = container.DisplayRectangle.Y;
foreach (var control in container.Controls.OfType<Control>().Where(c => c.Visible))
{
control.SetBounds(x, y,
bestSizedItem.testItemWidth,
bestSizedItem.testItemHeight);
x += bestSizedItem.testItemWidth + horizontalGap;
if (x + bestSizedItem.testItemWidth - horizontalGap > W)
{
x = container.DisplayRectangle.X;
y += bestSizedItem.testItemHeight + verticalGap;
}
}
}
我把Gist這個片段中,所以如果你願意,你可以作出貢獻。
您應該使用TableLayoutPanel而不是FlowLayoutPanel,但是您的文章沒有描述您將使用的邏輯確定您希望使用多少列和多少行。這個邏輯很可能是你的自定義代碼。 – LarsTech 2013-04-10 17:05:28
謝謝,實際上這是問題的一部分。我只是適應了一些描述。行的數量應該是(至少那會很好),隱含地確定圖像的當前數量和給定(固定)寬高比,例如對於所有圖像爲4:3。 – 2013-04-11 11:53:34