我动态地将帧填充到流动面板中(作为水平导向的VCL Metropolis应用程序的一部分)。我需要调整每个组的流程面板的大小,使其水平放置所有项目。我有一个非常简单的公式,有时可以做到这一点,但不是所有时间 - 特别是在添加奇数项时。流程面板的FlowStyle
设置为fsTopBottomLeftRight
,垂直放置2帧。
例如,添加7个项目会自动检测正确的宽度(4个项目)。但是添加5个项目并没有检测到正确的宽度(假设是3个横跨但是最终检测到2个)。
如何正确计算每组的宽度?
以下是将项目填充到每个项目组中的过程(删除了一些不相关的内容):
procedure TSplitForm.LoadScreen;
const
FRAME_WIDTH = 170; //Width of each frame
FRAME_HEIGHT = 250; //Height of each frame
FRAME_MARGIN = 30; //Margin to right of each group
FRAME_VERT_COUNT = 2; //Number of frames vertically stacked
var
CurGroup: TFlowPanel; //Flow panel currently being populated
procedure ResizeGroup(FP: TFlowPanel);
var
Count, CountHalf, NewWidth, I: Integer;
begin
//Resize the specific flow panel's width to fit all items
Count:= FP.ComponentCount;
NewWidth:= FRAME_WIDTH + FRAME_MARGIN; //Default width if no items
if Count > 0 then begin
//THIS IS WHERE MY CALCULATIONS DO NOT WORK
CountHalf:= Round(Count / FRAME_VERT_COUNT);
NewWidth:= (CountHalf * FRAME_WIDTH) + FRAME_MARGIN;
end;
if FP.Parent.Width <> NewWidth then
FP.Parent.Width:= NewWidth;
//Resize main flow panel's width to fit all contained group panels
//(automatically extends within scroll box to extend scrollbar)
Count:= TFlowPanel(FP.Parent.Parent).ControlCount;
NewWidth:= 0;
for I := 0 to Count-1 do begin
NewWidth:= NewWidth + FP.Parent.Parent.Controls[I].Width;
end;
NewWidth:= NewWidth + FRAME_MARGIN;
if FP.Parent.Parent.Width <> NewWidth then
FP.Parent.Parent.Width:= NewWidth;
end;
procedure Add(const Name, Title, Subtitle: String);
var
Frame: TfrmItemFrame;
begin
Frame:= AddItemFrame(CurGroup, Name); //Create panel, set parent and name
Frame.OnClick:= ItemClick;
Frame.Title:= Title;
Frame.Subtitle:= Subtitle;
ResizeGroup(CurGroup);
end;
begin
CurGroup:= fpMainGroup;
Add('boxMainItem1', 'Item 1', 'This is item 1');
Add('boxMainItem2', 'Item 2', 'This is item 2');
Add('boxMainItem3', 'Item 3', 'This is item 3');
Add('boxMainItem4', 'Item 4', 'This is item 4');
Add('boxMainItem5', 'Item 5', 'This is item 5');
CurGroup:= fpInventoryGroup;
Add('boxInventItem1', 'Item 1', 'This is item 1');
Add('boxInventItem2', 'Item 2', 'This is item 2');
Add('boxInventItem3', 'Item 3', 'This is item 3');
Add('boxInventItem4', 'Item 4', 'This is item 4');
Add('boxInventItem5', 'Item 5', 'This is item 5');
Add('boxInventItem6', 'Item 6', 'This is item 6');
Add('boxInventItem7', 'Item 7', 'This is item 7');
end;
这是该代码产生的截图:
正如你所看到的,第一组有5个项目隐藏了第5个项目,但第二个组有7个项目显示所有7个项目就好了。
父/子关系的结构是这样的(流程面板有问题粗体):
我尝试使用每个流程面板的AutoSize
属性,但它没有承认高度(2向上)并且使事情变得更糟。我基本上只需要正确检测这些流程图中的列总数。
答案 0 :(得分:3)
Round(Count / FRAME_VERT_COUNT);
此处FRAME_VERT_COUNT
为2
。当Count
为5
时,您的表达式变为
Rount(2.5);
默认的舍入模式是银行家四舍五入,评估为2
。当Count
为7
时,表达式为
Round(3.5);
银行家四舍五入意味着这是4
。
您可以执行Sertac建议并使用ceil
。但是,我完全避免浮点数。它只是不需要,作为一般规则,如果可行,整数算术总是首选。你的表达应该是
(Count + FRAME_VERT_COUNT - 1) div FRAME_VERT_COUNT
答案 1 :(得分:2)
您不需要部分图块,因此当您计算需要多少列时,您需要最接近的(等于或大于)整数。
在默认的舍入模式中,Round(7/2)
为&#39; 4&#39;。没关系。但是Round(5/2)
是&#39; 2&#39;。 That's because
使用默认的舍入模式(rmNearest),如果X恰好是中途 在两个整数之间,结果总是偶数。
只有两行,向上舍入可以是一个解决方案(除法总是一个整数或两个整数之间的数字)。对于一般解决方案,最好使用Ceil
。